我是golang的新手。我从游览开始。 这是go playground link
这是代码:
let port_string = DEFAULT_LISTENER_PORT.to_string();
let matches = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.arg(Arg::with_name("port")
.short("p")
.value_name("PORT")
.default_value(&port_string)
).get_matches();
这很着急
紧急:运行时错误:无效的内存地址或nil指针 取消引用 [信号SIGSEGV:细分违规代码= 0xffffffff addr = 0x0 pc = 0xd3ea6] goroutine 1 [正在运行]: main。(* T).M(0x0,0x434070)/tmp/sandbox696069628/main.go:15 + 0x26 main.main()/tmp/sandbox696069628/main.go:24 + 0x40
但是当我更改
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
func (t *T) M() {
fmt.Println(t.S)
}
func main() {
var i I
var t *T
i = t
i.M()
}
到
var t *T
i = t
它不再惊慌
两种情况下的行为都不应相似。如果没有,为什么?
答案 0 :(得分:3)
在两种情况下,您都在声明但未明确定义名为t
的变量。如果您未指定值,则会为变量的类型分配零值
所有指针类型(包括*T
)的零值为nil。结构类型的零值是该结构的值,所有字段均设置为零。
当为变量[...]分配存储空间且未提供显式初始化时,该变量或值将被赋予默认值。此类变量或值的每个元素的类型均设置为零:布尔值为false,数字类型为0,字符串为“”,指针,函数,接口,切片,通道和映射为nil。初始化是递归完成的,因此,例如,如果未指定任何值,则结构数组的每个元素的字段都将为零。
https://golang.org/ref/spec#The_zero_value
因此,这会将nil存储在接口值i
中:
var i interface{ M() }
var t *T
i = t
// i stores nil
这会在接口值i
中存储一个结构值:
var i interface{ M() }
var t T
i = t
// i stores T{S:""}
因此,在第一种情况下,(nil).M()
被称为(恐慌),在第二种情况下,(T{}).M()
被称为
答案 1 :(得分:2)
您没有初始化T。
这样做:
var t *T = &T{"Hello World"}