pointers - 如何在 Go 中的指针到指针上键入选择接口(interface)?

标签 pointers types interface casting go

我有一对这样定义的接口(interface):

type Marshaler interface {
    Marshal() ([]byte, error)
}

type Unmarshaler interface {
    Unmarshal([]byte) error
}

我有一个实现这些的简单类型:

type Foo struct{}

func (f *Foo) Marshal() ([]byte, error) {
    return json.Marshal(f)
}

func (f *Foo) Unmarshal(data []byte) error {
    return json.Unmarshal(data, &f)
}

我正在使用一个定义不同接口(interface)的库,并像这样实现它:

func FromDb(target interface{}) { ... }

传递给 target 的值是指向指针的指针:

fmt.Println("%T\n", target) // Prints **main.Foo

通常此函数执行类型切换,然后对下面的类型进行操作。我想为实现我的 Unmarshaler 接口(interface)的所有类型提供通用代码,但无法弄清楚如何从特定类型的指针到指针获取我的接口(interface)。

您不能在指向指针的指针上定义方法:

func (f **Foo) Unmarshal(data []byte) error {
    return json.Unmarshal(data, f)
}
// compile error: invalid receiver type **Foo (*Foo is an unnamed type)

您不能在指针类型上定义接收器方法:

type FooPtr *Foo

func (f *FooPtr) Unmarshal(data []byte) error {
    return json.Unmarshal(data, f)
}
// compile error: invalid receiver type FooPtr (FooPtr is a pointer type)

转换为 Unmarshaler 不起作用:

x := target.(Unmarshaler)
// panic: interface conversion: **main.Foo is not main.Unmarshaler: missing method Unmarshal

转换为 *Unmarshaler 也不起作用:

x := target.(*Unmarshaler)
// panic: interface conversion: interface is **main.Foo, not *main.Unmarshaler

我怎样才能从这个指针到指针类型获得我的接口(interface)类型而不需要打开每个可能的实现器类型?

最佳答案

它很丑陋,但是有可能有一个指向指针接收器的指针的语义等价物。例如:

package main

import "fmt"

type P *int

type W struct{ p P }

func (w *W) foo() {
        fmt.Println(*w.p)
}

func main() {
        var p P = new(int)
        *p = 42
        w := W{p}
        w.foo()
}

Playground


输出:

42

注意

fmt.Println(*w.p)

其实是上面的

fmt.Println(*(*w).p)

编译器会自动为您完成额外的工作。

关于pointers - 如何在 Go 中的指针到指针上键入选择接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18619089/

相关文章:

arrays - C 将指针传递给堆栈上的数组

C#: 类型名称 <type_name> 在类型 <type> 中不存在;在一个类中,调用另一个类的方法

arrays - Scala Array.apply 的魔力是什么

c++ - 了解 typeid().name() 的输出

function - 函数可以在 Go 中实现接口(interface)吗

dictionary - 我可以使用 defer 来删除映射的元素吗?

c - 使用指针点更改结构字段时出现指针错误

c++ - 通过 '*this' 传递拷贝时的奇怪行为

java - 如何在 Android 中使用一个接口(interface)与多个类

java - 为什么Iterable接口(interface)中的forEach方法不是抽象的?