gpt4 book ai didi

go - 当作为方法 arg 传递时,无类型常量 '\n' 如何转换为字节?

转载 作者:IT王子 更新时间:2023-10-29 00:55:18 24 4
gpt4 key购买 nike

我正在观看 FOSDEM '17 上关于在 Go 中实现“tail -f”的演讲 => https://youtu.be/lLDWF59aZAo

在作者最初的示例程序中,他使用文件句柄创建了一个Reader,然后使用带分隔符'\n'的ReadString方法读取文件行按行打印其内容。我通常使用 Scanner,所以这对我来说是新的。

下面的程序 | Go Playground Link

package main

import (
"bufio"
"fmt"
"log"
"os"
)

func main() {
fileHandle, err := os.Open("someFile.log")
if err != nil {
log.Fatalln(err)
return
}
defer fileHandle.Close()

reader := bufio.NewReader(fileHandle)

for {
line, err := reader.ReadString('\n')
if err != nil {
log.Fatalln(err)
break
}
fmt.Print(line)
}

}

现在,ReadString 将一个字节作为其分隔符参数[ https://golang.org/pkg/bufio/#Reader.ReadString]

所以我的问题是,'\n'(一个 rune)究竟是如何转换成一个 byte 的?我无法理解这个问题。特别是 byteuint8 的别名,而 runeint32 的别名。

我在 Gophers slack 中问了同样的问题,并被告知 '\n' 不是 rune,而是一个未类型化的常量。如果我们实际上使用 '\n' 创建了一个 rune 并将其传入,编译将失败。这实际上让我更加困惑。

我还得到了一个链接,指向 Go 规范中关于类型标识的部分 => https://golang.org/ref/spec#Type_identity

如果程序是一个实际的 rune 则不应该编译,为什么编译器允许未类型化的常量通过?这不是不安全的行为吗?

我的猜测是,由于 Assignability section in the Go spec 中的一条规则,这是有效的,它说

x is an untyped constant representable by a value of type T.

由于'\n'确实可以赋值给byte类型的变量,因此它被转换了。

我的推理是否正确?

最佳答案

TL;DR 是的你是对的,但还有更多。

'\n' 是一个未类型化的 rune 常量。它没有类型,但有一个默认类型,即int32(runeint32 的别名) .它包含一个表示文字“\n”的字节,即数值 10:

package main

import (
"fmt"
)

func main() {
fmt.Printf("%T %v %c\n", '\n', '\n', '\n') // int32 10 (newline)
}

https://play.golang.org/p/lMjrTFDZUM

规范中回答您问题的部分位于 § Calls (强调我的):

Given an expression f of function type F,

f(a1, a2, … an)

calls f with arguments a1, a2, … an. Except for one special case, arguments must be single-valued expressions assignable to the parameter types of F and are evaluated before the function is called.

"assignable"是这里的关键术语,您引用的规范部分解释了它的含义。正如您猜对的那样,在各种可分配性规则中,适用于此处的规则如下:

x is an untyped constant representable by a value of type T.

在我们的例子中,这转化为:

'\n' is an untyped (rune) constant representable by a value of type byte

在调用 ReadString() 时,'\n' 实际上被转换为一个字节,如果我们尝试传递一个宽度大于 1 字节的无类型 rune 常量,这一事实会更加明显, 到需要 byte 的函数:

package main

func main() {
foo('α')
}

func foo(b byte) {}

https://play.golang.org/p/W0EUZppWHH

上面的代码失败了:

tmp/sandbox120896917/main.go:9: constant 945 overflows byte

那是因为'α'实际上是2个字节,也就是说不能转换成byte类型的值(最大整数a byte 可以容纳的是 255 而 'α' 实际上是 945)。

所有这些都在官方博文中解释,Constants .

关于go - 当作为方法 arg 传递时,无类型常量 '\n' 如何转换为字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42744291/

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