Golang中如何让编译器不向原始字符串字面量添加首行换行符

Golang中如何让编译器不向原始字符串字面量添加首行换行符

func warn() {

	fmt.Fprintln(os.Stderr, "┌───────────────────────────┐")
	fmt.Fprintln(os.Stderr, "│                           │")
	fmt.Fprintln(os.Stderr, "│ warning! Run with caution │")
	fmt.Fprintln(os.Stderr, "│ warning! Run with caution │")
	fmt.Fprintln(os.Stderr, "│                           │")
	fmt.Fprintln(os.Stderr, "└───────────────────────────┘")

	// 但我希望只使用一次 `fmt.Fprint` 调用

	// 像这样

	msg := `
┌───────────────────────────┐
│                           │
│ warning! Run with caution │
│ warning! Run with caution │
│                           │
└───────────────────────────┘
`
	fmt.Fprint(os.Stderr, msg)

	// 但我无法去掉第一个换行符

	// 我可以把反引号 ` 放在行首

	msg =
`┌───────────────────────────┐
│                           │
│ warning! Run with caution │
│ warning! Run with caution │
│                           │
└───────────────────────────┘
`

	// 但这让代码看起来不美观
	// `go fmt` 会让它变得更糟

	// 经过 go fmt 格式化后
	msg =
		`┌───────────────────────────┐
│                           │
│ warning! Run with caution │
│ warning! Run with caution │
│                           │
└───────────────────────────┘
`

}

更多关于Golang中如何让编译器不向原始字符串字面量添加首行换行符的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

第一,代码会变得难看。

更多关于Golang中如何让编译器不向原始字符串字面量添加首行换行符的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这仅仅是为了移除换行符,工作量真不小。 我希望它能像打印出来的那样。

原始字符串必须是原始的,这就是为什么它被称为“原始字符串”。在Go语言中没有缩进的多行字符串。就这么简单。

如何才能在保持代码可读性和美观的同时做到这一点,而不需要用户使用更多函数或创建切片表达式。

原始字符串需要一种良好的语法。目前无法保留缩进级别。

Zig 语言有一种很酷的方法:https://ziglang.org/documentation/master/#Multiline-String-Literals

这带来了许多好处。

这里的问题是你的第一行中有一个换行符(就在标题短横线之前)。 你可以做两件事:(1) 将你的短横线标题移动到 msg:=… 这一行 或者提取一个子字符串并去掉换行符,所以

runes := []rune(msg)
safeSubstring := string(runes[1:])XXXXXXXXXXXXX")
fmt.Fprint(os.Stderr, safeSubstring )

Go语言中没有这样的语言结构。

要么使用不带换行符且需要大量转义的常规字符串,要么使用原始字符串,它们就是字面上的原始字符串。它们会完全按照你输入的样子呈现。

不过,你或许可以使用 strings.Join()

package main

import (
	"fmt"
	"strings"
)

func main() {
	var (
		lines = []string{
			"┌───────────────────────────┐",
			"│                           │",
			"│ warning! Run with caution │",
			"│ warning! Run with caution │",
			"│                           │",
			"└───────────────────────────┘",
		}
		block = strings.Join(lines, "\n")
	)

	fmt.Println(block)
}

在Go中,原始字符串字面量(raw string literal)会保留反引号内的所有字符,包括换行符。当你将反引号放在单独一行时,字符串开头会包含一个换行符。以下是几种解决方案:

方案1:使用字符串连接

通过将字符串拆分为多行并连接,避免首行换行符:

msg := "┌───────────────────────────┐\n" +
    "│                           │\n" +
    "│ warning! Run with caution │\n" +
    "│ warning! Run with caution │\n" +
    "│                           │\n" +
    "└───────────────────────────┘"
fmt.Fprint(os.Stderr, msg)

方案2:使用strings.TrimPrefix

在输出前移除开头的换行符:

msg := `
┌───────────────────────────┐
│                           │
│ warning! Run with caution │
│ warning! Run with caution │
│                           │
└───────────────────────────┘`
fmt.Fprint(os.Stderr, strings.TrimPrefix(msg, "\n"))

方案3:使用text/template

对于复杂的格式化需求,使用模板:

tmpl := `┌───────────────────────────┐
│                           │
│ warning! Run with caution │
│ warning! Run with caution │
│                           │
└───────────────────────────┘`
fmt.Fprint(os.Stderr, tmpl)

方案4:使用fmt.Sprintf

通过格式化字符串控制换行:

msg := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s",
    "┌───────────────────────────┐",
    "│                           │",
    "│ warning! Run with caution │",
    "│ warning! Run with caution │",
    "│                           │",
    "└───────────────────────────┘")
fmt.Fprint(os.Stderr, msg)

方案5:使用strings.Join

将多行文本作为切片元素处理:

lines := []string{
    "┌───────────────────────────┐",
    "│                           │",
    "│ warning! Run with caution │",
    "│ warning! Run with caution │",
    "│                           │",
    "└───────────────────────────┘",
}
msg := strings.Join(lines, "\n")
fmt.Fprint(os.Stderr, msg)

这些方案都能避免原始字符串字面量的首行换行符问题,同时保持代码的可读性。

回到顶部