相关疑难解决方法(0)

Golang中的值接收器与指针接收器?

我很不清楚在哪种情况下我会想要使用值接收器而不是总是使用指针接收器.
要从文档中回顾一下:

type T struct {
    a int
}
func (tv  T) Mv(a int) int         { return 0 }  // value receiver
func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
Run Code Online (Sandbox Code Playgroud)

文档还表示"对于类型,如基本类型,切片和小结构,值接收机是非常便宜,所以,除非所述方法的语义需要一个指针,一个值是接收机有效和明确的."

首先它说它"非常便宜",但更问题的是它比指针接收器便宜.所以我做了一个小的基准测试(gist上的代码)向我展示了,即使对于只有一个字符串字段的结构,指针接收器也更快.这些是结果:

// Struct one empty string property
BenchmarkChangePointerReceiver  2000000000               0.36 ns/op
BenchmarkChangeItValueReceiver  500000000                3.62 ns/op


// Struct one zero int property
BenchmarkChangePointerReceiver  2000000000               0.36 ns/op
BenchmarkChangeItValueReceiver  2000000000               0.36 ns/op
Run Code Online (Sandbox Code Playgroud)

(编辑:请注意第二点在较新的版本中无效,请参阅注释).
第二点它说,它是"高效和清晰",这更多的是品味问题,不是吗?就个人而言,我喜欢以任何方式使用相同的方式.效率在什么意义上?性能方面看来,指针几乎总是更有效率.使用一个int属性的少量测试运行显示Value接收器的最小优势(范围为0.01-0.1 ns/op)

有人能告诉我一个值接收器明显比指针接收器更有意义的情况吗?或者我在基准测试中做错了什么,我是否忽略了其他因素?

pointers function go

89
推荐指数
2
解决办法
2万
查看次数

如何从函数调用中获取返回值的指针?

我只需要一个指向time.Time的指针,所以下面的代码似乎无效:

./c.go:5:不能取时间地址.现在()

我只是想知道为什么?有没有办法做到这一点,除了先对变量赋值并获取变量的指针?

package main

import "time"
func main() {
    _ = &time.Now()
}
Run Code Online (Sandbox Code Playgroud)

pointers go

20
推荐指数
3
解决办法
6704
查看次数

如何在Go中存储对操作结果的引用?

好吧用文字描述它很难,但是假设我有一个存储int指针的地图,并希望将操作的结果存储为我的哈希中的另一个键:

m := make(map[string]*int)

m["d"] = &(*m["x"] + *m["y"])
Run Code Online (Sandbox Code Playgroud)

这不起作用,并给我错误: cannot take the address of *m["x"] & *m["y"]

思考?

dictionary pointers go

7
推荐指数
1
解决办法
1464
查看次数

Go struct方法允许类型混合?

我有一个简单的结构,只有一个方法:

type Person struct {
  name string
}

func (p Person) SetName(name string) {
  p.name = name
}
Run Code Online (Sandbox Code Playgroud)

以下输出:

dave := Person{}
dave.SetName("Dave")
fmt.Println(dave.name)
Run Code Online (Sandbox Code Playgroud)

将是空的,因为方法接收器接受一个值(或更准确地创建您传递的值的副本),因此它不会修改您的基础值.

如果我将方法更改为:

func (p *Person) SetName(name string) {
  p.name = name
}
Run Code Online (Sandbox Code Playgroud)

输出将是"戴夫".

现在我不明白的是我不应该在指针上调用方法吗?所以在初始化我的对象时我应该这样做:

dave := &Person{}
Run Code Online (Sandbox Code Playgroud)

而不是这个:

dave := Person{}
Run Code Online (Sandbox Code Playgroud)

另外使用go的反射包我试图找出以下值:

&Person
Run Code Online (Sandbox Code Playgroud)

并发现它是*人,这很好.当我打印值虽然我没有得到内存位置相比,当我打印指向int的指针的值时:

a := 4
fmt.Println(&a)
Run Code Online (Sandbox Code Playgroud)

我一直在阅读文档,提出问题,但是我学的越多,我就越想知道我是否遗漏了一些简单的东西,因为很多人并不认为这一切都让人困惑.

go

0
推荐指数
1
解决办法
164
查看次数

无法获取地图元素的地址

我想找出原因

x:= odsMap[segRef]
x.GetValue("@OriginDestinationKey")
Run Code Online (Sandbox Code Playgroud)

可以,但是不能:

odsMap[segRef].GetValue("@OriginDestinationKey")
Run Code Online (Sandbox Code Playgroud)

最后一个代码段显示以下错误:

cannot call pointer method on odsMap[segRef]go
cannot take the address of odsMap[segRef]
Run Code Online (Sandbox Code Playgroud)

这些错误发生在编译时(而不是运行时)。所以,我的主要问题是为什么我需要一个中间变量x来访问该函数?

关于变量的类型odsMapmap[string]XMLElement并且segRef是字符串。

谢谢。

methods dictionary pointers go

0
推荐指数
1
解决办法
63
查看次数

标签 统计

go ×5

pointers ×4

dictionary ×2

function ×1

methods ×1