面试题答案
一键面试- 值接收器和指针接收器的区别
- 值接收器:
- 方法接收的是结构体值的副本。这意味着对值接收器的任何修改都不会影响原始结构体实例。例如:
- 值接收器:
package main
import "fmt"
type Person struct {
Name string
}
func (p Person) SetNameValueReceiver(newName string) {
p.Name = newName
}
func main() {
person := Person{Name: "John"}
person.SetNameValueReceiver("Jane")
fmt.Println(person.Name) // 输出 John
}
- 值接收器适合于不需要修改结构体内部状态的方法,并且结构体本身比较小、复制成本低的情况。
- 指针接收器:
- 方法接收的是结构体的指针,对指针接收器的修改会直接影响原始结构体实例。例如:
package main
import "fmt"
type Person struct {
Name string
}
func (p *Person) SetNamePointerReceiver(newName string) {
p.Name = newName
}
func main() {
person := Person{Name: "John"}
person.SetNamePointerReceiver("Jane")
fmt.Println(person.Name) // 输出 Jane
}
- 指针接收器适合于需要修改结构体内部状态的方法,或者结构体比较大,复制成本高的情况。
2. 性能优化场景
- 值接收器适合场景:
- 当结构体比较小且方法不需要修改结构体状态时,使用值接收器。例如,一个简单的
Point
结构体,只有两个int
类型的字段X
和Y
,用于计算点到原点距离的方法可以使用值接收器。
- 当结构体比较小且方法不需要修改结构体状态时,使用值接收器。例如,一个简单的
package main
import (
"fmt"
"math"
)
type Point struct {
X int
Y int
}
func (p Point) DistanceToOrigin() float64 {
return math.Sqrt(float64(p.X*p.X + p.Y*p.Y))
}
func main() {
point := Point{X: 3, Y: 4}
fmt.Println(point.DistanceToOrigin())
}
- 指针接收器适合场景:
- 当结构体较大或者方法需要修改结构体状态时,使用指针接收器。比如一个包含大量字段的用户信息结构体
UserInfo
,如果有方法要更新用户信息,就应该使用指针接收器。
- 当结构体较大或者方法需要修改结构体状态时,使用指针接收器。比如一个包含大量字段的用户信息结构体
package main
import "fmt"
type UserInfo struct {
Name string
Age int
Address string
// 更多字段...
}
func (u *UserInfo) UpdateAge(newAge int) {
u.Age = newAge
}
func main() {
user := UserInfo{Name: "Alice", Age: 25, Address: "123 Street"}
user.UpdateAge(26)
fmt.Println(user.Age)
}