这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记.
第三部分 错误处理与strings包操作
3.1 错误处理(error)
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
error类型是一个接口类型,这是它的定义:
type error interface {
Error() string
}
我们可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现
}
在下面的例子中,我们在调用Sqrt的时候传递的一个负数,然后就得到了non-nil的error对象,将此对象与nil比较,结果为true,所以fmt.Println(fmt包在处理error时会调用Error方法)被调用,以输出错误,请看下面调用的示例代码:
result, err:= Sqrt(-1)
if err != nil {
fmt.Println(err)
}
需要注意的一点是,error.New()函数每次都会返回一个不同的错误值,即使文本是相同的;
所以不能拿error类型直接进行比较
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
// New returns an error that formats as the given text.
// 即便文本相同,每次调用errors.New()函数都会返回一个不同的错误值。因此不能直接拿error类型做比较。
// exp : err1, err2 := errors.New("not found"), errors.New("not found")
// fmt.Println(err1 == err2) // false
return nil, errors.New("not found")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name) // wang
if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err) // not found
return
} else {
fmt.Println(u.name)
}
}
3.2 strings包函数
package main
import (
"fmt"
"strings"
)
func main() {
a := "hello"
// strings包
fmt.Println(strings.Contains(a, "ll")) // 是否包含: true
fmt.Println(strings.Count(a, "l")) // 包含几个: 2
fmt.Println(strings.HasPrefix(a, "he")) // 是否有该前缀: true
fmt.Println(strings.HasSuffix(a, "llo")) // 是否有该后缀: true
fmt.Println(strings.Index(a, "ll")) // 最早出现的索引: 2
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // 用分隔符sep连接成字符串: he-llo
fmt.Println(strings.Repeat(a, 2)) // 重复: hellohello
fmt.Println(strings.Replace(a, "e", "E", -1)) // 替换: hEllo
fmt.Println(strings.Split("a-b-c", "-")) // 字符串分割成数组: [a b c]
fmt.Println(strings.ToLower(a)) // 小写: hello
fmt.Println(strings.ToUpper(a)) // 大写: HELLO
fmt.Println(len(a)) // 长度: 5
b := "你好"
fmt.Println(len(b)) // 6
}
Go的string包具有几个可用于字符串数据类型的功能 。 这些功能使我们可以轻松地修改和操作字符串。 我们可以将函数视为对代码元素执行的操作。 内置函数是用Go编程语言定义的函数,可供我们随时使用。
字符串搜索功能 (String Search Functions)
strings包具有许多有助于确定字符串是否包含特定字符序列的功能。
| Function | Use |
|---|---|
strings.HasPrefix | Searches the string from the beginning |
strings.HasSuffix | Searches the string from the end |
strings.Contains | Searches anywhere in the string |
strings.Count | Counts how many times the string appears |
strings.HasPrefix和strings.HasSuffix允许您检查字符串是否以一组特定字符开头或结尾。
例如,检查字符串"Sammy Shark"以Sammy开头并以Shark结尾:
ss := "Sammy Shark"
fmt.Println(strings.HasPrefix(ss, "Sammy")) // true
fmt.Println(strings.HasSuffix(ss, "Shark")) // true
您将使用strings.Contains函数来检查"Sammy Shark"包含序列Sh :
fmt.Println(strings.Contains(ss, "Sh")) // true
最后,看看字母S在短语Sammy Shark出现了多少次:
fmt.Println(strings.Count(ss, "S")) // 2
注意,这里的函数都区分大小写
字符串操作的功能 (Functions for String Manipulation)
strings.Join , strings.Split和strings.ReplaceAll函数是在Go中处理字符串的其他几种方法。
strings.Join函数用于将字符串的切片组合为新的单个字符串。
fmt.Println(strings.Join([]string{"sharks", "crustaceans", "plankton"}, ","))
// output : sharks,crustaceans,plankton
如果要在新字符串中的字符串值之间添加逗号和空格,则可以简单地在逗号后用空格重写表达式: strings.Join([]string{"sharks", "crustaceans", "plankton"}, ", ") (此处有空格)。
就像我们可以将字符串连接在一起,我们同样也可以拆分字符串。 为此,我们可以使用strings.Split函数并在空格处进行分割:
balloon := "Sammy has a balloon."
s := strings.Split(balloon, " ")
fmt.Println(s) // [Sammy has a balloon] 这里变成了字符串切片,[]string
输出是字符串的切片。 由于使用了strings.Println ,因此很难通过查看来判断输出是什么。 要查看它确实是字符串的切片,请使用带有%q动词的fmt.Printf函数对字符串加引号:
fmt.Printf("%q", s)
// Output : ["Sammy" "has" "a" "balloon."]
strings.ReplaceAll函数可以采用原始字符串,并返回更新后的字符串并进行替换。
假设Sammy拥有的气球丢了。 由于Sammy不再具有此气球,因此我们将新字符串中的子字符串"has"从原始字符串balloon更改为"had" :
fmt.Println(strings.ReplaceAll(balloon, "has", "had"))
// Output: Sammy had a balloon.
在括号内,第一个是balloon ,用于存储原始字符串的变量。 第二个子字符串"has"是我们要替换的东西,第三个子字符串"had"是我们要替换第二个子字符串的东西。 将其合并到程序中后,输出将如上所示
使字符串大写和小写 (Making Strings Uppercase and Lowercase)
函数strings.ToUpper和strings.ToLower将返回一个字符串,其中原始字符串的所有字母都转换为大写或小写字母。 因为字符串是不可变的数据类型,所以返回的字符串将是新的字符串。 字符串中任何非字母的字符都不会更改。
要将字符串"Sammy Shark"转换为全部大写,可以使用strings.ToUpper函数:
ss := "Sammy Shark"
fmt.Println(strings.ToUpper(ss)) // SAMMY SHARK
fmt.Println(strings.ToLower(ss)) // sammy shark
strings.ToUpper和strings.ToLower函数通过使大小写一致来strings.ToLower评估和比较字符串的过程。 例如,如果用户将其姓名全写为小写,则仍然可以通过将其姓名与全大写字母进行比较来确定他们的姓名是否在我们的数据库中。
确定字符串长度 (Determining String Length)
内置函数len()返回字符串中的字符数。 当您需要强制使用最小或最大密码长度,或将较大的字符串截断为特定的限制以用作缩写时,此功能很有用。
为了演示此功能,我们将找到一个长句子字符串的长度:
import (
"fmt"
"strings"
)
func main() {
openSource := "Sammy contributes to open source."
fmt.Println(len(openSource)) // 33
}
我们将变量openSource设置为等于字符串"Sammy contributes to open source." 然后使用len(openSource)将该变量传递给len()函数。 最后,我们将该函数传递给fmt.Println()函数,以便我们可以在屏幕上看到程序的输出。
请记住, len()函数将计算由双引号引起的任何字符,包括字母,数字,空格字符和符号。