温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

golang常用的字符串处理方式

发布时间:2020-06-15 17:00:15 来源:亿速云 阅读:309 作者:元一 栏目:编程语言

Go语言概念

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。

罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在Linux及Mac OS X平台上进行了实现,后来追加了Windows系统下的实现。在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”。 目前,Go每半年发布一个二级版本(即从a.x升级到a.y)。

字符串概念
字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 s="a1a2···an"(n>=0)。它是编程语言中表示文本的数据类型。在程序设计中,字符串(string)为符号或数值的一个连续序列,如符号串(一串字符)或二进制数字串(一串二进制数字)。

1、多行字符串

str := `This is a
multiline
string.`

注意 - 任何你在字符串中的缩进都将被保留在最终结果。

str := `This string
    will have
    tabs in it`

2. 高效的字符串连接方式

Go 允许你通过 "+" 的方式连接字符串,但这种方式在处理大量字符串连接的场景下将非常低效。使用 bytes.Buffer 连接字符串是一个更高效的方式,它会一次性将所有的内容连接起来转化成字符串。

package main
import (
    "bytes"
    "fmt"
)
func main() {
    var b bytes.Buffer
    for i := 0; i < 1000; i++ {
        b.WriteString(randString())
    }
    fmt.Println(b.String())
}
func randString() string {
    // 模拟返回一个随机字符串
    return "abc-123-"
}

如果你提前准备好所有字符串,你也可以通过 strings.Join 的方式实现。

package main
import (
    "fmt"
    "strings"
)
func main() {
    var strs []string
    for i := 0; i < 1000; i++ {
        strs = append(strs, randString())
    }
    fmt.Println(strings.Join(strs, ""))
}
func randString() string {
    // 模拟返回一个随机字符串
    return "abc-123-"
}

3. 将整型 (或任意数据类型) 转为字符串

在大多数语言中,可轻易地将任意数据类型转型为字符串进行拼接,或用字符串插入(例如在 ruby 中这样 "ID=#{id}")。很不幸,如果你尝试在 Go 中去做这种显示而易见的操作,比如强制将整形转为字符串,你不会得到期望的结果。

i := 123
s := string(i)

你希望 s 的输出是多少?如果你像大多数人一样猜测 "123",那你就大错特错了。相反,你会得到类似 "E" 的值。这根本不是我们想要的!

相反,您应该使用像 [strconv] (https://golang.org/pkg/strconv/) 这样的包或像 fmt.Sprintf 这样的函数。例如,下面是一个使用 strconv.Itoa 将整数转换为字符串的示例。

package main
import (
    "fmt"
    "strconv"
)
func main() {
    i := 123
    t := strconv.Itoa(i)
    fmt.Println(t)
}

你还可以使用 fmt.Sprintf 函数将几乎所有数据类型转换为字符串,但通常应保留在这样的实例上,如正在创建的字符串包含嵌入数据,而非在期望将单个整数转换为字符串时用。

package main
import "fmt"
func main() {
    i := 123
    t := fmt.Sprintf("We are currently processing ticket number %d.", i)
    fmt.Println(t)
}

Sprintf 的操作与 fmt.Printf 几乎相同,只是它没有将结果字符串输出到标准输出,而是将其作为字符串返回。

限制使用 Sprintf

如前所述,fmt.Sprintf 通常应用在创建具有嵌入值的字符串。这有几个原因,但最突出的一个原因是 fmt.Sprintf 不做任何类型检查,因此在实际运行代码之前,您不太可能发现任何错误。

Sprintf 也比你通常在 strconv 包中使用的大多数函数慢,不过如果我说实话,速度差异是如此之小,一般不值得考虑。

4. 创建随机字符串

这并不是一个真正的「快速技巧」,但我发现这是一个经常被问到的问题。

如何在 Go 中创建随机的字符串?

听上去很简单。许多语言,比如 Ruby 和 Python,都提供了一些帮助程序,使随机字符串的生成变得非常简单,所以 Go 肯定有这样一个工具,对吧?答案是错误的。

Go 选择只提供创建随机字符串的工具,而将细节留给开发人员。虽然一开始可能会有些困难,但好处是您可以完全决定如何生成字符串。 这意味着您可以指定字符集、如何播种随机生成以及任何其他详细信息。简而言之,你有更多的控制权,但代价是需要写一些额外的代码。

下面是一个使用 math/rand 包和一组字母数字字符作为字符集的快速示例。

package main
import (
    "fmt"
    "math/rand"
    "time"
)
func main() {
    fmt.Println(RandString(10))
}
var source = rand.NewSource(time.Now().UnixNano())
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
func RandString(length int) string {
    b := make([]byte, length)
    for i := range b {
        b[i] = charset[source.Int63()%int64(len(charset))]
    }
    return string(b)
}

Go 练习场总是输出相同的字符串

如果您在 Go 练习场上多次运行这段代码,您可能会注意到它总是输出相同的字符串 - aJFLa7XPH5。

这是因为 Go 练习场总是使用相同的时间,所以当我们用 rand.NewSource 方法时。在当前时间内传递的那个值总是相同的,所以我们生成的字符串总是相同的。

对于您的特定需求,可能有比这个更优的解决方案,但这是一个很好的起点。如果您正在寻找改进 / 更改代码的方法,您可能会考虑使用 crypto/rand 包来生成随机数据 — 这通常更安全,但最终可能需要更多的工作。

无论您最终使用的是什么,这个示例都应该有助于您入门。 对于大多数不涉及密码和身份验证系统等敏感数据的实际用例,它工作得足够好。 只是一定要记得你的种子随机数发生器!这可以通过 rand.Seed 函数在 math/rand 包中完成,或者创建一个源代码。在上面的例子中,我选择创建一个源代码。

5. strings 包、HasPrefix 和自定义代码

在处理字符串时,想要知道一个字符串是以一个特定的字符串开始还是以一个特定的字符串结束是非常常见的情况。例如,如果您的 API 键都以 sk_ 开头,那么您可能希望验证 API 请求中提供的所有 API 键都以这个前缀开头,否则进行数据库查找将浪费大量时间。

对于那些听起来像是非常常见的用例的函数,您最好的选择通常是直接访问 strings 包并检查一些可能对您有帮助的内容。在这种情况下,你会想要使用功能 HasPrefix(str, prefix) 和 strings.HasSuffix(str, prefix)。 你可以在下面看到他们的用法。

package main
import (
    "fmt"
    "strings"
)
func main() {
    fmt.Println(strings.HasPrefix("something", "some"))
    fmt.Println(strings.HasSuffix("something", "thing"))
}

虽然 strings 包中有大量有用的公共函数,但值得注意的是,并不总是值得去寻找一个能满足您需要的包。如果你有其他语言经验正在学习 Go 语言,一个常见的错误是开发者花太多时间寻找能够提供所需功能的包,而他们自己可轻易地编码实现这功能。

使用标准库肯定有好处(如它们经过了彻底的测试并有很好的文档记录)。尽管有这些好处,但如果你发现自己花了超过几分钟的时间来寻找一个函数,那么自己编写它通常也是有益的。在这种情况下,根据需求自定义(编码),将很快完成,你将完全了解正在发生的事情,不会被奇怪的边界情况(译者注如索引越界)措手不及。您也不必担心其他人维护代码。

6. 字符串可以被转换成 byte 切片 (反之亦然)

Go 语言可以将一个字符串转换成 byte 切片 ([]byte) ,也可以将 byte 切片转换成字符串。转换的过程跟其他任意类型转换的方式一样简单。这种转换方式通常用于为一个接收 byte 切片参数的函数传递一个字符串 以及 为一个接收字符串参数的函数传递 byte 切片的场景。

下面是一个转换的例子:

package main
import "fmt"
func main() {
    var s string = "this is a string"
    fmt.Println(s)
    var b []byte
    b = []byte(s)
    fmt.Println(b)
    for i := range b {
        fmt.Println(string(b[i]))
    }
    s = string(b)
    fmt.Println(s)
}

以上就是常见的 Go 处理字符串的技巧的详细内容,更多请关注亿速云其它相关文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI