亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

有沒有更好的方法來實現模仿有限字符顯示的水平滾動文本效果?

有沒有更好的方法來實現模仿有限字符顯示的水平滾動文本效果?

Go
婷婷同學_ 2023-08-14 14:31:50
我試圖在命令行上模仿 16 個字符的顯示,它在一個長字符串上循環,無限類似于股票交易股票。現在,我首先打印 ASCII 字符串的前 16 字節切片,并一次移動 1 個字節:package mainimport (    "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)    }}當我到達文本末尾時,我重置循環內的計數器并從第一個切片開始再次打印。我不想這樣做,而是想獲得“翻轉”效果,其中切片的頭部無縫連接到切片的尾部。問題是,我不能使用空緩沖區并將頭部附加到循環內的尾部,因為它會無限增長。因此,我沒有這樣做,而是決定在循環之前將字符串的前 16 個字節附加到其尾部,并立即縮小切片 -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 相當陌生,所以我想知道是否有更好的方法來達到相同的結果?
查看完整描述

1 回答

?
慕碼人8056858

TA貢獻1803條經驗 獲得超6個贊

首先我不會改變緩沖區。0將前 16 個字符附加到其末尾以輕松獲得“滾動”效果是一個好主意,但是當您到達末尾時將位置重置到更容易且更便宜。

接下來,您不需要對字節切片進行操作。只需在string.?字符串可以像切片一樣進行索引和切片,并且切片 astring甚至不會進行復制(不必),它會返回一個新字符串(標頭),該字符串共享字符串數據的后備數組。不要忘記索引和切片string使用字節索引(不是rune索引),這對于 ASCII 文本來說很好(它們的字符在 UTF-8 中一對一映射到字節),但不適用于多字節特殊字符。你的示例文本很好。

也不要用于fmt.Printf()打印需要格式的文本string(將其第一個參數視為格式字符串)。相反,只需使用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]


查看完整回答
反對 回復 2023-08-14
  • 1 回答
  • 0 關注
  • 138 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號