英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论