变量和函数的返回值的行为不同

huangapple go评论84阅读模式
英文:

Different behavior of variable and return value of function

问题

我想要将两行代码合并,但是我收到了一个错误信息。

原始代码:

hash := sha1.Sum([]byte(uf.Pwd))
u.Pwhash = hex.EncodeToString(hash[:])

合并后的代码:

u.Pwhash = hex.EncodeToString(sha1.Sum([]byte(uf.Pwd))[:])

第一段代码可以正常工作,但是第二段代码会产生以下错误信息:

models/models.go:104: invalid operation sha1.Sum(([]byte)(uf.Pwd))[:] (slice of unaddressable value)

为什么会出现这个错误?

英文:

I want to join two lines, but I get an error message.

Original:

hash := sha1.Sum([]byte(uf.Pwd))
u.Pwhash = hex.EncodeToString(hash[:])

Joint:

u.Pwhash = hex.EncodeToString(sha1.Sum([]byte(uf.Pwd))[:])

The first one works fine, the second produces the error message:

models/models.go:104: invalid operation sha1.Sum(([]byte)(uf.Pwd))[:] (slice of unaddressable value)

Why is that?

答案1

得分: 8

你在第二种情况下出现错误信息,是因为你尝试对函数调用的返回值进行切片操作(即sha1.Sum(([]byte)(uf.Pwd))[:])。

函数调用的返回值是不可寻址的。作为提醒,只有以下内容是可寻址的(来自规范:地址操作符):

  • 变量、指针间接引用或切片索引操作;
  • 可寻址结构操作数的字段选择器;
  • 可寻址数组的数组索引操作。作为可寻址要求的例外情况,x也可以是一个(可能带括号的)复合字面量

而对数组进行切片操作需要该数组是可寻址的。根据规范:切片表达式

  • 如果被切片的操作数是一个数组,它必须是可寻址的,切片操作的结果是一个与数组具有相同元素类型的切片。

你的第一种情况可以正常工作,是因为你首先将返回的数组存储在一个可寻址的局部变量中。

对数组进行切片操作需要数组是可寻址的,因为切片操作会生成一个切片,该切片不会复制数组的数据,而是创建一个与其共享底层数组的切片,并且只会指向或引用该数组。

英文:

You get an error message in the 2nd case because you try to slice the return value of a function call (that of sha1.Sum()):

sha1.Sum(([]byte)(uf.Pwd))[:]

The return values of function calls are not addressable. As a reminder, (only) the following are addressable (taken from Spec: Address operators):

> ...a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.

And slicing an array requires the array to be addressable. Spec: Slice expressions:

> If the sliced operand is an array, it must be addressable and the result of the slice operation is a slice with the same element type as the array.

Your first case works because you first store the returned array in a local variable which is addressable.

Slicing an array requires the array to be addressable because slicing results in a slice which will not copy the data of the array but create a slice which shares the backing array and will only point/refer to it.

huangapple
  • 本文由 发表于 2015年9月28日 16:49:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/32818994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定