【问题标题】:How can I assign a new char into a string in Go?如何在 Go 中将新字符分配给字符串?
【发布时间】:2014-11-05 21:14:39
【问题描述】:

我正在尝试更改 Go 中的现有字符串,但我不断收到此错误“无法分配给 new_str[i]”

package main
import "fmt"

func ToUpper(str string) string {
    new_str := str
    for i:=0; i<len(str); i++{
        if str[i]>='a' && str[i]<='z'{
            chr:=uint8(rune(str[i])-'a'+'A')
            new_str[i]=chr
        }
    }
    return new_str
}

func main() {
    fmt.Println(ToUpper("cdsrgGDH7865fxgh"))
}

这是我的代码,我希望将小写字母改为大写字母,但我无法更改字符串。为什么?怎么改?

P.S 我只想使用 fmt 包!

提前致谢。

【问题讨论】:

  • 您是否有什么特别的原因不想使用标准库中的strings.ToUpper 函数?

标签: string go uppercase alter toupper


【解决方案1】:

你不能……它们是不可变的。来自Golang Language Specification

字符串是不可变的:一旦创建,就不可能改变字符串的内容。

但是,您可以将其转换为 []byte 切片并更改它:

func ToUpper(str string) string {
    new_str := []byte(str)
    for i := 0; i < len(str); i++ {
        if str[i] >= 'a' && str[i] <= 'z' {
            chr := uint8(rune(str[i]) - 'a' + 'A')
            new_str[i] = chr
        }
    }
    return string(new_str)
}

工作样本:http://play.golang.org/p/uZ_Gui7cYl

【讨论】:

    【解决方案2】:

    使用range 并避免不必要的转换和分配。字符串是不可变的。例如,

    package main
    
    import "fmt"
    
    func ToUpper(s string) string {
        var b []byte
        for i, c := range s {
            if c >= 'a' && c <= 'z' {
                if b == nil {
                    b = []byte(s)
                }
                b[i] = byte('A' + rune(c) - 'a')
            }
        }
        if b == nil {
            return s
        }
        return string(b)
    }
    
    func main() {
        fmt.Println(ToUpper("cdsrgGDH7865fxgh"))
    }
    

    输出:

    CDSRGGDH7865FXGH

    【讨论】:

      【解决方案3】:

      在 Go 中,字符串是不可变的。这是做你想做的事的一种非常糟糕的方式 (playground)

      package main
      
      import "fmt"
      
      func ToUpper(str string) string {
          new_str := ""
          for i := 0; i < len(str); i++ {
              chr := str[i]
              if chr >= 'a' && chr <= 'z' {
                  chr = chr - 'a' + 'A'
              }
              new_str += string(chr)
          }
          return new_str
      }
      
      func main() {
          fmt.Println(ToUpper("cdsrgGDH7865fxgh"))
      }
      

      这很糟糕,因为

      • 您将字符串视为字符 - 如果它是 UTF-8 怎么办?使用range str 是可行的方法
      • 附加到字符串很慢 - 大量分配 - bytes.Buffer 是个好主意
      • 已经有一个非常好的库例程可以做到这一点strings.ToUpper

      值得进一步探索new_str += string(chr)这一行。字符串是不可变的,所以它的作用是创建一个末尾带有 chr 的新字符串,它不会扩展旧字符串。这对于长字符串来说非常低效,因为分配的内存将趋向于字符串长度的平方。

      下次使用strings.ToUpper

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        • 2010-10-09
        • 1970-01-01
        相关资源
        最近更新 更多