在go/golang中表示换行的最便携/跨平台方式是什么?

car*_*ion 26 portability cross-platform newline go

目前,为了代表go程序中的换行符,我使用了\n.例如:

package main

import "fmt"


func main() {
    fmt.Printf("%d is %s \n", 'U', string(85))
}
Run Code Online (Sandbox Code Playgroud)

...将产生85 is U后续换行符.

但是,这似乎不是跨平台的.看看其他语言,PHP用全局常量(PHP_EOL)表示它.\n在go/golang中以跨平台特定方式表示换行符的正确方法是什么?

dsk*_*ner 18

我对此感到好奇,所以决定看看到底是做了什么fmt.Println.http://golang.org/src/pkg/fmt/print.go

如果您滚动到最底部,你会看到一个if addnewline地方\n,总是使用.如果这是最"跨平台"的方式,我不能说话,而且早期最初与linux绑定,但这就是std lib的用武之地.

我原本打算建议使用fmt.Fprintln,这可能仍然有效,好像当前功能不合适,可以提交错误,然后代码只需要使用最新的Go工具链进行编译.

  • 可以将 "\n" 直接打印到某个输出流,因为当此输出流是非二进制时启用换行符转换。这是 Go 所基于的 C 运行时库的一个属性:它自动将行尾转换为平台使用的行尾,因此在程序代码中仅使用“\n”是安全的。但这仅适用于非二进制流,并且仅使用 C 运行时获取平台行分隔符(例如作为字符串)并不容易。 (4认同)
  • @VladimirMatveev,你确定Go是基于C运行时吗?似乎它的标准编译器不依赖于C运行时并产生静态链接的二进制文件,它们也不依赖于任何东西. (4认同)
  • @kostix,看来你是对的.通过Go I/O机制的内部结构表明,他们在Unix系统上使用POSIX`open()`syscall,在Windows系统上使用`CreateFile`来打开文件.提供给`os.File#Write`的缓冲区似乎直接发送到Windows`WriteFile` API函数.Windows API函数不执行行结束转换,因此如果源中只有LF,则输出将仅包含LF. (2认同)
  • @VladimirMatveev,顺便说一句,我最近实现了一个简单文本文件的解析,基本上使用“bufio.ReadString()”,并且我想我还想为这样的任务提供一个更高级的函数,它会读取直到“\r\n”或“\n”(单个“\r”似乎不再相关)并返回文本*不*包括EOL序列。例如,这就是 Tcl 的“gets”的工作原理。但这确实是 golang-nuts 上讨论的话题...... (2认同)

Jer*_*all 12

让操作系统确定在多个上下文中出现的换行符是错误的.你真正想知道的是"记录"分隔符是什么,Go假定你是程序员应该知道的.

即使二进制文件在Windows上运行,它也可能正在消耗Unix OS中的文件.

行结尾取决于文件或文档的来源是什么,而不是二进制文件运行的操作系统.


juc*_*rdi 7

您始终可以使用特定于操作系统的文件来声明某些常量.就像_test.go文件只在执行时一样go test,_[os].go只有在构建到目标平台时才包含这些文件.

基本上你需要添加以下文件:

 - main.go
 - main_darwin.go     // Mac OSX
 - main_windows.go    // Windows
 - main_linux.go      // Linux
Run Code Online (Sandbox Code Playgroud)

您可以在每个main_[os].go文件中声明一个LineBreak常量,并将逻辑放入其中main.go.

您文件的内容如下所示:

main_darwin.go

package somepkg

const LineBreak = "\n"
Run Code Online (Sandbox Code Playgroud)

main_linux.go

package somepkg

const LineBreak = "\n"
Run Code Online (Sandbox Code Playgroud)

main_windows.go

package somepkg

const LineBreak = "\r\n"
Run Code Online (Sandbox Code Playgroud)

只需在您的main.go文件中,编写代码并参考LineBreak

main.go

package main

import "fmt"


func main() {
    fmt.Printf("%d is %s %s", 'U', string(85), LineBreak)
}
Run Code Online (Sandbox Code Playgroud)