package main
import "fmt"
type MyService struct {
Name string
}
func (s *MyService) PName() {
fmt.Printf("name1 %s\n", s.Name)
s.Name = "zhangsan"
fmt.Printf("name2 %s\n", s.Name)
}
func main() {
var service MyService
service.PName()
fmt.Printf("name3 %s\n", service.Name)
}
///output
name1
name2 zhangsan
name3 zhangsan
代码很简单,无法理解的是 var service MyService 。根据我目前看的学习文档,这个只是声明了一个变量,其类型为 MyService ,而没有绑定到任何内存区域,为什么后续的方法调用没出现空指针报错呢.赋值 Name 也成功了。百思不得其解
1
zxdstyle 2023-06-19 10:37:28 +08:00 1
|
2
renyijiu 2023-06-19 10:38:15 +08:00 1
var 定义之后没有赋值,默认是一个 zero value, 其中 name 字段是 string ,所以是个空字符串。
|
3
serco 2023-06-19 10:38:16 +08:00
没用过 go ,随便看了一下,你说的这句实际上已经是实例化了一个 struct
看这个的案例 https://www.tutorialsteacher.com/go/struct#:~:text=In%20Go%20lang%2C%20struct%20(structure,the%20type%20and%20struct%20keywords. You can declare an instance and assign values later on using a dot, as shown below. ``` var s4 Student s4.id = 4 s4.name = "Abdul" s4.grade = 8 fmt.Println(s4) //output: {4 Abdul 8} var s5 Student s5.name = "Sachin" fmt.Println(s5) //output: {0 Sachin 0} ``` |
4
NX2023 2023-06-19 10:41:39 +08:00
在我的印象里声明一个变量的时候都会自动初始化为零值,完全不要操心
|
5
Nazz 2023-06-19 10:42:04 +08:00
go 有空值安全特性
|
6
dobelee 2023-06-19 10:44:55 +08:00 1
这个不是指针类型。下面这个才是。你的写法是初始化零值。
var service *MyService |
7
moqimoqide 2023-06-19 10:45:29 +08:00
帮问了一下 gpt:
在 Go 语言中,如果结构体类型的实例被声明为值类型变量(而不是指针类型变量)时,在调用该结构体类型的方法时,会自动进行值拷贝( pass by value )。换言之,值类型变量作为一个参数传递给方法时,方法会获取该值类型变量的一份拷贝,当方法需要修改该结构体类型实例的值时,它修改的只是拷贝中的相应值,而不是原来的变量。所以调用顺序如下: 1. 执行 service.PName() 方法时,会将 MyService 类型的 service 的一份拷贝传递给 PName() 方法。 2. 在 PName() 方法中,首先打印出 s.Name 的值,由于此时 Name 字段还没有被初始化,因此打印出的结果为空字符串。 3. 接下来,将 s.Name 的值更改为 "zhangsan"。 4. 继而,打印出 s.Name 的值,此时 Name 字段的值已经被更改为 "zhangsan",因此打印出的结果为 "zhangsan"。 5. PName() 方法执行结束,返回到 main() 函数中。 6. 在 main() 函数中,打印出 service.Name 的值,此时打印出的是 "zhangsan"。 因此,在你的代码中,var service MyService 声明了一个值类型的 MyService 变量,该结构体实例会被分配内存空间并初始化(其中包括 Name 字段),但在调用 PName() 方法时,会将 service 的一份拷贝传递给该方法,因此执行 PName() 方法会修改拷贝中的 Name 字段的值,但不会影响原来的 service 变量。 |
8
buffzty 2023-06-19 10:51:23 +08:00 1
var service MyService
等于 var service = MyService{} 等于 service:= MyService{} |
9
jiekeop OP 谢谢各位解答,明白了
|
10
LeegoYih 2023-06-19 10:58:25 +08:00
Go 反直觉的地方多了去了,学 Go 不能代入其他语言的思维。
无忌,你忘干净了吗? |
11
lilei2023 2023-06-19 11:28:52 +08:00
这个我刚学也比较懵
|
12
Cola98 2023-06-19 13:31:06 +08:00
因为这是一个浅拷贝,第一个 name1 没有赋值,所以就给了默认值就是"",接着你 name2 为 zhangsan ,name3 会接着用之前的值
|