簡體   English   中英

為什么不正確地將非指針值調用的閉包添加到切片中?

[英]Why don't closures called from non-pointer values ​be added to slices correctly?

這是go1.12.3 linux/amd64的參數。

通過變量x向包含函數的slice s添加了兩個閉包。 通過使用類型為T的指針接收器的方法獲得閉包。 通過變量x向包含函數的slice s添加了兩個閉包。 通過使用類型為T的指針接收器的方法獲得閉包。

package main

import "fmt"

type T struct {
    X int
}

func (t *T) f() func() {
    return func() { fmt.Println(t.X) }
}

func good() {
    s := []func(){}

    x := &T{1}
    s = append(s, x.f())

    x = &T{2}
    s = append(s, x.f())

    s[0]() // => 1
    s[1]() // => 2
}

func bad() {
    s := []func(){}

    x := T{1}
    s = append(s, (&x).f())  // Even if it rewrites to append(s, x.f()), the result is the same.

    x = T{2}
    s = append(s, (&x).f())

    s[0]() // => 2 WHY!?
    s[1]() // => 2
}

func main() {
    good()
    bad()
}

https://play.golang.org/p/j-818FZELQb

在以上兩個函數中, good()可以正常工作。 好的s[0]()執行T{1}.f()() ,而s s[1]()執行T{2}.f()() 但是, bad()運行s[0]()s[1]()運行T{2}.f()() 即使我將元素添加到切片時也沒有覆蓋它!

我不知道是什么原因導致了這種現象。 不變量x具有類型的值T而不是指針類型的值T 還是我不知道append的調用規范?

請給我一些建議。

因為在糟糕的情況下,您只有一個類型T的變量x ,而一個變量只有一個地址,因此,當您開始調用函數時,切片s始終包含相同的函數,且該函數作用於具有值2的同一變量。

(好的,您有兩個不同的T類型變量。您重用了* T類型的變量(x),但仍然有兩個不同的 T具有不同的值。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM