gpt4 book ai didi

go - Golang 接口(interface)上的指针接收器和值接收器

转载 作者:数据小太阳 更新时间:2023-10-29 03:42:41 26 4
gpt4 key购买 nike

这个问题没有我想的那么清楚我会问一个更好的问题。但我不想在上面标记重复。所以我提出了我自己的问题。如果您可以帮助将其删除,以免混淆社区。请只做那些需要的。请不要对我投反对票。抱歉不清楚

我是 golang 的新手,刚刚掌握它的窍门。

我正在学习围棋之旅,然后根据自己的理解使用它。我在Interfaces,开始用自己的理解去实现。这是 Go PlayGround Link

第 1 步:我创建了 3 种类型:int、struct 和 interface

package main

import (
"fmt"
)

type MyInt int

type Pair struct {
n1, n2 int
}

type twoTimeable interface {
result() (int, int)
}

第 2 步:然后我为指针接收器实现了 twoTimeable,因为它改变了基础值。

func (p *Pair) result() (int, int) {
p.n1 = 2 * p.n1
p.n2 = 2 * p.n2
return p.n1, p.n2
}

func (m *MyInt) result() (int, int) {
*m = 2 * (*m)
return int(*m), 0
}

第 3 步:然后我在 main 函数中声明并分配了 MyInt、Pair 和它们对应的指针。我还声明了 twoTimeable 接口(interface)

mtemp := MyInt(2)
var m1 MyInt
var m2 *MyInt
var p1 Pair
var p2 *Pair
m1, m2, p1, p2 = MyInt(1), &mtemp, Pair{3, 4}, &Pair{5, 6}
var tt twoTimeable

fmt.Println(" Values : ", m1, *m2, p1, *p2, tt)

第 4 步:我分配 MyInt、Pair 和它们的指针,调用实现的方法并打印。

tt = m1
fmt.Println(tt.result())
fmt.Printf("Value of m1 %v\n", m1)

tt = m2
fmt.Println(tt.result())
fmt.Printf("Value of m2 %v\n", *m2)

tt = p1
fmt.Println(tt.result())
fmt.Printf("Value of p1 %v\n", p1)

tt = p2
fmt.Println(tt.result())
fmt.Printf("Value of p2 %v\n", *p2)

显示错误:

prog.go:41:5: cannot use m1 (type MyInt) as type twoTimeable in assignment:
MyInt does not implement twoTimeable (result method has pointer receiver)
prog.go:49:5: cannot use p1 (type Pair) as type twoTimeable in assignment:
Pair does not implement twoTimeable (result method has pointer receiver)

我还阅读了 this question ,我知道 m1 和 p1 不可寻址,这就是它无法编译的原因。但是,如果我使用 p1 或 m1 p1/m1.result()(自动取消引用 FTW)

,方法 result() 将正常工作

现在在第 2 步中,当我将指针接收器更改为值接收器,并将 *m 更改为 m(我知道输出中的更改)

func (p Pair) result() (int, int) {
p.n1 = 2 * p.n1
p.n2 = 2 * p.n2
return p.n1, p.n2
}

func (m MyInt) result() (int, int) {
m = 2 * (m)
return int(m), 0
}

突然不显示编译错误了。不应该用于 m2 和 p2,因为现在没有使用 *MyInt 和 *Pair

的结果实现

这意味着如果接口(interface)方法实现有值接收者 tt 可以同时持有指针和值。但是当接口(interface)方法实现有指针接收者时,它不能容纳非指针。

Q1 : Why it is fine to use pointers (tt = m2) on value receiver interface methods(p MyInt) result() , but not values (tt = m1) on pointer receiver interface method(p *MyInt) result().

现在让我们回到指针接收器。

Is there a way that if function accept param (tt twoTimeable) i will be able to invoke tt.result() irrespective tt being a pointer to type or not, given result() is only definded with pointer receiver.

请看下面的代码:

func doSomething(tt twoTimeable) {
temp1, temp2 := tt.result()
fmt.Print("doing something with ", temp1, temp2)
}

因为 tt 可以是任何预定义类型(指针或不是指针),接受参数(tt *twoTimeable,如果我能做到的话)似乎不是解决方案,或者我是否依赖函数的用户提供指针.如果我不必更改基础值,即使用值接收器,这不是问题,因为 tt 可以保存值或指向该值的指针

我总是接受答案。

最佳答案

Q1 : Why it is fine to use pointers on value receiver methods but not vice vers?

因为语言规范说得很好:https://golang.org/ref/spec#Method_sets :

The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T).

(规范是这样的一个可能的原因:方便。)

对于剩下的问题:我完全不知道你在问什么。 do Something 的代码完全没问题。您在 tt 上调用 result,它是实现 result() (int, int) 方法的任何类型。此类型是否为指针类型无关紧要。您从这个方法调用中得到两个 int 并且可以用这些 int 做任何您想做的事。

(关于“接口(interface)指针”部分:是的。从技术上讲,ttp *twoTimetable 是可行的。但是您永远不需要这个。永远。(当然这是一个谎言,但你需要它的情况是如此罕见和微妙,以至于你作为初学者真的永远不需要它,一旦你需要它,你就会知道如何使用它。)这里要记住一件事:你永远不会做“指向接口(interface)的指针”。)

关于go - Golang 接口(interface)上的指针接收器和值接收器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53701458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com