我只需要一个指向time.Time的指针,所以下面的代码似乎无效:
./c.go:5:不能取时间地址.现在()
我只是想知道为什么?有没有办法做到这一点,除了先对变量赋值并获取变量的指针?
package main
import "time"
func main() {
_ = &time.Now()
}
Run Code Online (Sandbox Code Playgroud) 好吧用文字描述它很难,但是假设我有一个存储int指针的地图,并希望将操作的结果存储为我的哈希中的另一个键:
m := make(map[string]*int)
m["d"] = &(*m["x"] + *m["y"])
Run Code Online (Sandbox Code Playgroud)
这不起作用,并给我错误: cannot take the address of *m["x"] & *m["y"]
思考?
Go FAQ 回答了一个关于方法中按值与按指针接收器定义选择的问题。该答案中的陈述之一是:
如果该类型的某些方法必须有指针接收器,其余的也应该如此,因此无论如何使用该类型,方法集都是一致的。
这意味着,如果我对一个数据类型有一些改变数据的方法,因此需要按指针接收器,我应该对为该数据类型定义的所有方法使用按指针接收器。
另一方面,"fmt"包通过 value调用接口中String()定义的方法。如果用接收器按指针定义方法,则当关联的数据类型作为参数提供给(或其他格式化方法)时,将不会调用该方法。这让人们别无选择,只能使用接收器按值实现该方法。StringerString()fmt.PrintlnfmtString()
正如常见问题解答所建议的那样,在满足接口fmt要求的同时,如何与按值与按指针的选择保持一致Stringer?
编辑:
为了强调我提到的问题的本质,考虑一个数据类型,其中包含一组用接收者按值定义的方法(包括 String())。然后一个人希望添加一个额外的方法来改变该数据类型 - 所以他用接收者按指针定义它,并且(为了保持一致,每个常见问题解答)他还更新了该数据类型的所有其他方法以供使用- 指针接收器。此更改对使用此数据类型方法的任何代码的影响为零 - 但用于调用fmt格式化函数(现在需要将指针传递给变量而不是其值,就像更改之前一样)。因此,一致性要求仅在fmt. 需要调整提供变量的方式fmt.Println (或类似功能)基于接收器类型打破了轻松重构一个包的能力。
在下一个代码中,第一个代码Println在构建时失败并出现错误slice of unaddressable value。其余的线条都很好。
package main
import "fmt"
func getSlice() [0]int {
return [...]int{}
}
func getString() string {
return "hola"
}
func main() {
fmt.Println(getSlice()[:]) // Error: slice of unaddressable value
var a = getSlice()
fmt.Println(a[:])
fmt.Println(getString()[:])
var b = getString()
fmt.Println(b[:])
}
Run Code Online (Sandbox Code Playgroud)
如果第一个Println被评论它就有效。
试试看
这是为什么?我在这里缺少什么?