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

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

我可以使用 make 或 new 在 golang 中制作預填充字符串嗎?

我可以使用 make 或 new 在 golang 中制作預填充字符串嗎?

Go
呼喚遠方 2023-03-29 15:28:42
我正在嘗試在 Go 中優化我的 stringpad 庫。到目前為止,我發現用已知字符值(例如 0 或“”)填充字符串(實際上是 bytes.Buffer)的唯一方法是使用 for 循環。代碼片段是:// PadLeft pads string on left side with p, c timesfunc PadLeft(s string, p string, c int) string {    var t bytes.Buffer    if c <= 0 {        return s    }    if len(p) < 1 {        return s    }    for i := 0; i < c; i++ {        t.WriteString(p)    }    t.WriteString(s)    return t.String()}我相信 string pad 越大,t 緩沖區的內存副本就越多。有沒有更優雅的方法來制作一個已知大小的緩沖區,并在初始化時使用已知值?
查看完整描述

1 回答

?
弒天下

TA貢獻1818條經驗 獲得超8個贊

您只能使用make()new()分配已清零的緩沖區(字節片或數組)。您可以使用復合文字來獲取最初包含非零值的切片或數組,但您不能動態描述初始值(索引必須是常量)。

從類似但非常有效的strings.Repeat()函數中獲取靈感。它以給定的計數重復給定的字符串:

func Repeat(s string, count int) string {

? ? // Since we cannot return an error on overflow,

? ? // we should panic if the repeat will generate

? ? // an overflow.

? ? // See Issue golang.org/issue/16237

? ? if count < 0 {

? ? ? ? panic("strings: negative Repeat count")

? ? } else if count > 0 && len(s)*count/count != len(s) {

? ? ? ? panic("strings: Repeat count causes overflow")

? ? }


? ? b := make([]byte, len(s)*count)

? ? bp := copy(b, s)

? ? for bp < len(b) {

? ? ? ? copy(b[bp:], b[:bp])

? ? ? ? bp *= 2

? ? }

? ? return string(b)

}

strings.Repeat()進行一次分配以獲得工作緩沖區(這將是一個字節 slice?[]byte),并使用內置copy()函數復制可重復的字符串。值得注意的一件事是它使用工作副本并嘗試逐步復制整個副本,這意味著例如如果字符串已被復制 4 次,則復制此緩沖區將使其成為 8 次,等等。這將最大限度地減少對copy().?該解決方案還利用了copy()可以從 a 復制字節string而無需將其轉換為字節片的優勢。

我們想要的是類似的東西,但我們希望將結果添加到字符串之前。

我們可以考慮到這一點,只需分配一個內部使用的緩沖區Repeat()加上我們左填充的字符串的長度。

結果(不檢查參數count):

func PadLeft(s, p string, count int) string {

? ? ret := make([]byte, len(p)*count+len(s))


? ? b := ret[:len(p)*count]

? ? bp := copy(b, p)

? ? for bp < len(b) {

? ? ? ? copy(b[bp:], b[:bp])

? ? ? ? bp *= 2

? ? }

? ? copy(ret[len(b):], s)

? ? return string(ret)

}

測試它:


fmt.Println(PadLeft("aa", "x", 1))

fmt.Println(PadLeft("aa", "x", 2))

fmt.Println(PadLeft("abc", "xy", 3))

輸出(在Go Playground上嘗試):


xaa

xxaa

xyxyxyabc


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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