为什么这个匿名func返回相同的struct实例?

时间:2013-05-25 13:42:29

标签: go

package main

import "fmt"

type fake struct {
}

func main() {
    f := func() interface{} {
        return &fake{}
    }

    one := f()
    two := f()

    fmt.Println("Are equal?: ", one == two)
    fmt.Printf("%p", one)
    fmt.Println()
    fmt.Printf("%p", two)
    fmt.Println()
}

http://play.golang.org/p/wxCUUCyz98

为什么这个匿名func会返回所请求类型的相同实例,如何在每次调用时返回一个新实例?

2 个答案:

答案 0 :(得分:6)

您将两个接口与one == two进行比较。让我们看看language specification对这个表达式含义的看法:

  

界面值具有可比性。如果两个接口值相等   它们具有相同的动态类型和相同的动态值,或者两者都有   没有价值。

     

指针值具有可比性。如果它们两个指针值相等   指向相同的变量或者两者的值都为零。指针   不同的零大小变量可能相等也可能不相等。

在您的示例中,onetwo都是接口值,并且它们具有相同的动态类型(*fake)。它们的动态值都是指向零大小对象的指针,正如您在上面所读到的,在这种情况下,相等可能也可能不成立。

鉴于此,您可以通过不使用指向零大小结构的指针作为唯一值来解决您的问题。也许使用int代替?

这可能是这样的:

type fake int

func main() {
    var uniq fake
    f := func() interface{} {
        uniq++
        return uniq
    }
    ...
}

目前还不清楚你想要达到的目标,所以这对你来说可能是一个很好的解决方案。

答案 1 :(得分:1)

语言规范的最后一段:

  

如果结构或数组类型不包含任何字段(或   元素,分别),大小大于零。二   不同的零大小变量在内存中可能具有相同的地址。

http://golang.org/ref/spec#Size_and_alignment_guarantees

正如在接受的答案中所指出的,如果您使用非空结构,您将看到您的期望。