如何在golang中通过引用传递结构体类型的接口?

9

我需要按照下面的方式通过引用传递一个结构类型的接口。由于我不能使用指向接口的指针来修改结构类型变量,那么我应该如何更改下面的代码以将 te 的值修改为 10?。

package main

import (
    "fmt"
)

func another(te *interface{}) {
    *te = check{Val: 10}
}

func some(te *interface{}) {
    *te = check{Val: 20}
    another(te)
}

type check struct {
    Val int
}

func main() {
    a := check{Val: 100}
    p := &a
    fmt.Println(*p)
    some(p)
    fmt.Println(*p)
}

谢谢!

附言:我读到过传递接口指针不是很好的做法。请告诉我如何更好地处理它。


1
Go语言没有传递引用的概念。 - Volker
@Volker:抱歉我用词不当,但我希望你能理解我的问题意图。 - re3el
1
要在Go中实现类似于引用传递的操作,您需要使用指针。 - Lasse V. Karlsen
@LasseV.Karlsen:你能提供一个例子吗?我尝试使用指针但没有成功。 - re3el
不好意思,我只是在阅读文档。我从未使用过Go语言。在Go语言中,每个参数都是按值传递的,但你可以通过传递指针(按值)来实现引用传递。 - Lasse V. Karlsen
3
为什么需要传递接口的指针?如果你传递一个指向你的结构体的指针,而这个结构体实现了所需的接口,那么你仍然会有一个指向具体对象的指针。试图改变底层对象的事实似乎表明你可能不理解接口的目的。 - Gavin
2个回答

14

所以你正在使用一个接口,并且需要某种保证,以便可以设置结构体的成员变量值?听起来你应该将这个保证作为接口的一部分,例如:

type Settable interface {
    SetVal(val int)
}

func (c *check) SetVal(val int) {
    c.Val = val
}

func some(te Settable) {
    te.SetVal(20)
}

type check struct {
    Val int
}

func main() {
    a := check{Val: 100}
    p := &a
    some(p)
    fmt.Println(*p)
}

4
只是澄清一下:some(a) 无法编译,因为 check 没有实现 Settablesome(&a) 可以工作,因为 *check 实现了 Settable。顺便说一句,您可能希望删除 p 变量,并使用 some(&a)fmt.Println(a) 来显示该函数实际上正在更改 a 而不仅仅是 p,因为新的 Gopher 可能会认为您正在更改 p 而不是 a - Adirio

0

类似以下代码应该可以实现

func some(te interface{}) {
    switch te.(type) {
    case *check:
        *te.(*check) = check{Val: 20}
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接