gpt4 book ai didi

string - 有没有更好的方法来实现模仿有限字符显示的水平滚动文本效果?

转载 作者:行者123 更新时间:2023-12-02 18:30:17 25 4
gpt4 key购买 nike

我正在尝试在命令行上模仿 16 个字符的显示,该显示在一个长字符串上循环,无限类似于证券交易所股票代码。

现在,我首先打印 ASCII 字符串的前 16 字节 slice ,并一次移动 1 个字节:

package main

import (
"fmt"
"time"
)

const (
chars = 16
text = "There are many variations of passages of Lorem Ipsum available!!!"
)

func main() {
fmt.Print("\033[2J") // clear screen
buf := []byte(text)

i := chars
for {
fmt.Print("\033[H") // move cursor back to first position
fmt.Printf(string(buf[i-chars : i]))
i++

if i == len(buf)+1 {
i = chars
}

time.Sleep(time.Second / 4)

// visualization of what's happening:
// fmt.Printf("\t\t Character:%d of Length:%d | Slice: %d:%d \n", i, len(buf), i-chars, i)
}
}

当我到达文本末尾时,我重置循环内的计数器并从第一个 slice 开始再次打印。我不想这样做,而是想获得“翻转”效果,其中 slice 的头部无缝连接到 slice 的尾部。

问题是,我不能使用空缓冲区并将头部附加到循环内的尾部,因为它会无限增长。

因此,我没有这样做,而是决定在循环之前将字符串的前 16 个字节附加到其尾部,并立即将 slice 缩小 -16 个字节。但由于 -16 字节仍然存在于支持数组中,我可以从循环中扩展/收缩:

func main() {
fmt.Print("\033[2J") // clear screen
buf := []byte(text)
buf = append(buf, buf[:chars]...)
buf = buf[:len(buf)-chars]

var expanded bool
i := chars
for {
fmt.Print("\033[H") // move cursor back to first position
fmt.Printf(string(buf[i-chars : i]))
i++

if i+1 == len(buf)-chars && !expanded {
buf = buf[:len(buf)+chars]
expanded = true
}

if i+1 == len(buf) {
i = chars
buf = buf[:len(buf)-chars]
expanded = false
}

time.Sleep(time.Second / 2)

// visualization of what's happening:
//fmt.Printf("\t\t Character:%d of Length:%d | Slice: %d:%d | Cap: %d\n", i, len(buf), i-chars, i, cap(buf))
}
}

这让我到达了我想要的地方,但我对 Go 还很陌生,所以我想知道是否有更好的方法来实现相同的结果?

最佳答案

首先我不会改变缓冲区。将前 16 个字符附加到其末尾以轻松获得“滚动”效果是一个好主意,但是当到达末尾时将位置重置为 0 会更容易且更便宜.

接下来,您不需要对字节 slice 进行操作。只需对字符串进行操作即可。字符串可以被索引和 slice ,就像 slice 一样,并且 slice string 甚至不需要复制(不是必须),它返回一个共享后备数组的新字符串( header )的字符串数据。不要忘记索引和 slice string 使用字节索引(而不是 rune 索引),这对于 ASCII 文本来说很好(它们的字符一对一映射到字节)以 UTF-8 表示),但不适用于多字节特殊字符。您的示例文本很好。

也不要使用fmt.Printf()打印需要格式字符串的文本(将其第一个参数视为格式字符串)。相反,只需使用 fmt.Print() .

总而言之,您的解决方案可以简化为这样,这在性能方面要好得多,而且更干净、更简单:

func main() {
fmt.Print("\033[2J") // clear screen
s := text + text[:chars]

for i := 0; ; i = (i + 1) % len(text) {
fmt.Print("\033[H") // move cursor back to first position
fmt.Print(s[i : i+chars])
time.Sleep(time.Second / 2)
}
}

另请注意,当位置达到 len(text) 时,我们将其重置为 0,因此之前的文本以 text< 的最后一个字符开始 并从一开始就使用 chars-1 。因此附加 chars-1 而不是 chars 也足够了:

s := text + text[:chars-1]

关于string - 有没有更好的方法来实现模仿有限字符显示的水平滚动文本效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59269259/

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