上篇文章思考题
结果:cannot use number2 + 10 (type int) as type int64 in assignment
注意:uint8就是byte,编译通过,但是int和int64需要显示转换
字符型
没有,推荐使用byte或rune,仅包含Ascii码时,使用byte,其余使用rune。
字母一个字节,汉字3个字节
存储过程:字符->码值(数字)->二进制->保存
直接输出为数字,按字符使用 %c
a := 'a' fmt.Printf("a的类型%T,a的值:%v,a对应的字符:%c,a的大小:%d\n",a,a,a,unsafe.Sizeof(a)) you := '你' fmt.Printf("you的类型%T,you的值:%v,you对应的字符:%c,you的大小:%d\n",you,you,you,unsafe.Sizeof(you))
字符串型
src->builtin->builtin.go
// string is the set of all strings of 8-bit bytes, conventionally but not // necessarily representing UTF-8-encoded text. A string may be empty, but // not nil. Values of string type are immutable. type string string
由byte组成,是byte数组,不可以变,直接输出可以
str1 := "hello" str2 := "你好" fmt.Println("str1 str2:",str1,str2)
内存
src->reflect->value.go
// StringHeader is the runtime representation of a string. // It cannot be used safely or portably and its representation may // change in a later release. // Moreover, the Data field is not sufficient to guarantee the data // it references will not be garbage collected, so programs must keep // a separate, correctly typed pointer to the underlying data. type StringHeader struct { Data uintptr Len int }
目前,在go 1.16.3中是使用指针和长度的结构体表示,以后可能会修改。
1. world := "world" world1 := "世界" fmt.Printf("world:%v world1:%v world:%T,world1:%T\n", world,world1,world,world1) fmt.Println("&world[0] &world1 len(world) len(world1):",&world,&world1,len(world),len(world1)) // &world[0] 不允许取地址
你可以访问world[0],但是不能访问world[0]的地址 &world[0],出于安全考虑。
原始字符串
双引号"识别转义字符,反引号`原生形式输出
str3 := "我要换行\n换好啦:)\n" str4 := `我想换行\n换不了:(\n`
返回子串
类似Python的切片,没有步长,左闭右开,左右相等时为空,左默认为0,右默认为字符串长度
fmt.Println("world[:3] world1[3:]:",world[:3],world1[3:])
返回子串
类似Python的切片,没有步长,左闭右开,左右相等时为空,左默认为0,右默认为字符串长度
fmt.Println("world[:3] world1[3:]:",world[:3],world1[3:])
拼接
使用+,放不下时,+保留在上一行
str5 := str1+world+ str2+world1
修改
使用切片
1. tmp := []byte(world) tmp[0] = 'W' world = string(tmp) fmt.Println("world &world",world,&world)
注意:地址相同,确实是修改了
遍历
for或for range
for i:=0;i<len(world1);i=i+3{ fmt.Print(world1[i:i+3]) } for _,s := range world1{ fmt.Printf("%c",s) }
注意:中文是3个取一次,否则没意义。推荐使用for range方式,有字符和中文时都可以。
strings包
比较
==
注意:严格区分大小写
EqualFold
func EqualFold(s, t string) bool
判断两个utf-8编码字符串(将unicode大写、小写、标题三种格式字符视为相同)是否相同。
alpha := "abc" alpha2 := "Abc" fmt.Println("alpha==alpha2 strings.EqualFold(alpha,alpha2):", alpha==alpha2,strings.EqualFold(alpha,alpha2))
大小写转换
func ToLower(s string) string
返回将所有字母都转为对应的小写版本的拷贝。
func ToUpper(s string) string
返回将所有字母都转为对应的大写版本的拷贝。
fmt.Println("",strings.ToUpper(alpha),strings.ToLower(alpha2))
去前后缀
func TrimSpace(s string) string
返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。
func Trim(s string, cutset string) string
返回将s前后端所有cutset包含的utf-8码值都去掉的字符串。
func TrimLeft(s string, cutset string) string
返回将s前端所有cutset包含的utf-8码值都去掉的字符串。
func TrimRight(s string, cutset string) string
返回将s后端所有cutset包含的utf-8码值都去掉的字符串。
song := " \n\t两只\t老虎\t爱跳舞\n " fmt.Println("去空格 去空格和两只 去空格和两 去空格和跳舞:",strings.TrimSpace(song),strings.Trim(song," \n\t两只"), strings.TrimLeft(song," \n\t两"),strings.TrimRight(song," \n两跳舞"))
注意:TrimSpace将\t等也算为Space,指定时是字符集,在其中就算,直到左/右侧不在集合中停止。
判断前后缀
func HasPrefix(s, prefix string) bool
判断s是否有前缀字符串prefix。
func HasSuffix(s, suffix string) bool
判断s是否有后缀字符串suffix。
fmt.Println("song[4:]有两只前缀吗? song有爱跳舞后缀吗?",strings.HasPrefix(song[4:],"两只"),strings.HasSuffix(song,"爱跳舞"))
拆分与拼接
func Split(s, sep string) []string
用去掉s中出现的sep的方式进行分割,会分割到结尾,并返回生成的所有片段组成的切片(每一个sep都会进行一次切割,即使两个sep相邻,也会进行两次切割)。如果sep为空字符,Split会将s切分成每一个unicode码值一个字符串。
func Join(a []string, sep string) string
将一系列字符串连接为一个字符串,之间用sep来分隔。
ip := "192.168.31.129" slice := strings.Split(ip,".") newIp := strings.Join(slice,"?")
子串
包含
func Contains(s, substr string) bool
判断字符串s是否包含子串substr。
fmt.Println("song包含老虎吗? ",strings.Contains(song,"老虎"))
统计
func Count(s, sep string) int
返回字符串s中有几个不重复的sep子串。
fmt.Println("ip中有几个.? ",strings.Count(ip,"."))
查找
func Index(s, sep string) int
子串sep在字符串s中第一次出现的位置,不存在则返回-1。
func LastIndex(s, sep string) int
子串sep在字符串s中最后一次出现的位置,不存在则返回-1。
fmt.Println("ip中第一个1的下标 ip中最后一个1的下标:",strings.Index(ip,"1"),strings.LastIndex(ip,"1"))
替换
func Replace(s, old, new string, n int) string
返回将s中前n个不重叠old子串都替换为new的新字符串,如果n<0会替换所有old子串。
fmt.Println("将ip中的.替换为*",strings.Replace(ip,".","*",-1))
类型转换函数Atoi等在数据转换文章,更多方法,查看参考的包
bytes包和strings包的函数差不多,只不过参数由string变为了[]byte,可以看下参考的Go标准库,这里就不展示了。
查看源代码也经常能看到官方的骚操作,比如bytes.Equal
func Equal(a, b []byte) bool { return string(a) == string(b) }
unicode包
此包主要针对字符rune类型
func IsDigit(r rune) bool
IsDigit报告一个字符是否是十进制数字字符。
ok := unicode.IsDigit(rune(ip[0])) fmt.Printf("%c是十进制数字? %t\n",ip[0],ok)
是否是数字字符
func IsNumber(r rune) bool
IsNumber报告一个字符是否是数字字符
ok = unicode.IsNumber(rune(ip[0])) fmt.Printf("%c是数字字符? %t\n",ip[0],ok)
是否是字母
func IsLetter(r rune) bool
IsLetter报告一个字符是否是字母
ok = unicode.IsLetter(rune(alpha[0])) fmt.Printf("%c是字母? %t\n",alpha[0],ok)
是否是小写字母
func IsLower(r rune) bool
返回字符是否是小写字母
ok = unicode.IsLower(rune(ip[0])) fmt.Printf("%c是小写字母? %t\n",ip[0],ok)
是否是大写字母
func IsUpper(r rune) bool
返回字符是否是大写字母。
ok = unicode.IsUpper(rune(alpha2[0])) fmt.Printf("%c是大写字母? %t\n",alpha2[0],ok)
返回对应的大写字母
func ToUpper(r rune) rune
返回对应的大写字母,不是字母是返回原字符。
fmt.Printf("%c转换为大写字母是%c\n",ip[0],unicode.ToUpper(rune(ip[0])),)
返回对应的小写字母
func ToLower(r rune) rune
返回对应的小写字母,不是字母是返回原字符。
fmt.Printf("%c转换为小写字母是%c\n",alpha2[0],unicode.ToLower(rune(alpha2[0])))
全部代码
package main import ( "fmt" "strings" "unicode" "unsafe" ) func main() { //------------------字符型------------------- a := 'a' fmt.Printf("a的类型%T,a的值:%v,a对应的字符:%c,a的大小:%d\n",a,a,a,unsafe.Sizeof(a)) you := '你' fmt.Printf("you的类型%T,you的值:%v,you对应的字符:%c,you的大小:%d\n",you,you,you,unsafe.Sizeof(you)) //-----------------字符串-------------------- str1 := "hello" str2 := "你好" fmt.Println("str1 str2:",str1,str2) //-----------------内存---------------------- world := "world" world1 := "世界" fmt.Printf("world:%v world1:%v world:%T,world1:%T\n", world,world1,world,world1) fmt.Println("&world[0] &world1 len(world) len(world1):",&world,&world1,len(world),len(world1)) // &world[0] 不允许取地址 //-----------------原始字符串---------------- str3 := "我要换行\n换好啦:)\n" str4 := `我想换行\n换不了:(\n` fmt.Printf("str3:%vstr4:%v\n",str3,str4) //----------------子串---------------------- fmt.Println("world[:3] world1[3:]:",world[:3],world1[3:]) //---------------拼接----------------------- str5 := str1+world+ str2+world1 fmt.Println("str5:",str5) //--------------修改(重新赋值)------------- tmp := []byte(world) tmp[0] = 'W' world = string(tmp) fmt.Println("world &world",world,&world) //-------------遍历------------------------ for i:=0;i<len(world1);i=i+3{ fmt.Print(world1[i:i+3]) } for _,s := range world1{ fmt.Printf("%c",s) } fmt.Println() //--------------比较----------------------- alpha := "abc" alpha2 := "Abc" fmt.Println("alpha==alpha2 strings.EqualFold(alpha,alpha2):", alpha==alpha2,strings.EqualFold(alpha,alpha2)) //-------------大小写转换------------------- fmt.Println("",strings.ToUpper(alpha),strings.ToLower(alpha2)) //------------去除空格-------------------- song := " \n\t两只\t老虎\t爱跳舞\n " fmt.Println("去空格 去空格和两只 去空格和两 去空格和跳舞:",strings.TrimSpace(song),strings.Trim(song," \n\t两只"), strings.TrimLeft(song," \n\t两"),strings.TrimRight(song," \n两跳舞")) //------------判断前后缀---------------- fmt.Println("song[4:]有两只前缀吗? song有爱跳舞后缀吗?",strings.HasPrefix(song[4:],"两只"),strings.HasSuffix(song,"爱跳舞")) //-------------拆分与拼接-------------- ip := "192.168.31.129" slice := strings.Split(ip,".") newIp := strings.Join(slice,"?") fmt.Println("ip newIP:",ip,newIp) //--------------------------------子串-------------------------------- //-------------包含------------------- fmt.Println("song包含老虎吗? ",strings.Contains(song,"老虎")) //------------统计------------------- fmt.Println("ip中有几个.? ",strings.Count(ip,".")) //----------查找-------------------- fmt.Println("ip中第一个1的下标 ip中最后一个1的下标:",strings.Index(ip,"1"),strings.LastIndex(ip,"1")) //----------替换------------------- fmt.Println("将ip中的.替换为*",strings.Replace(ip,".","*",-1)) //----------------------------------判断------------------------------- ok := unicode.IsDigit(rune(ip[0])) fmt.Printf("%c是十进制数字? %t\n",ip[0],ok) ok = unicode.IsNumber(rune(ip[0])) fmt.Printf("%c是数字字符? %t\n",ip[0],ok) ok = unicode.IsLetter(rune(alpha[0])) fmt.Printf("%c是字母? %t\n",alpha[0],ok) ok = unicode.IsLower(rune(ip[0])) fmt.Printf("%c是小写字母? %t\n",ip[0],ok) ok = unicode.IsUpper(rune(alpha2[0])) fmt.Printf("%c是大写字母? %t\n",alpha2[0],ok) fmt.Printf("%c转换为小写字母是%c\n",alpha2[0],unicode.ToLower(rune(alpha2[0]))) fmt.Printf("%c转换为大写字母是%c\n",ip[0],unicode.ToUpper(rune(ip[0])),) }
截图
参考
补充
字符串内部存储与取出
S := "ab" for i,s := range S{ fmt.Printf("%T %T %T\n",i,s,S[i]) }
int int32 uint8
int int32 uint8
取出的是rune,存储的是byte
思考题
以下代码会输出什么?
sentence := "我是lady_killer9" for i :=0;i<len(sentence);i++{ fmt.Printf("%c",sentence[i]) }
答案见下一篇文章:Go-基本数据类型转换详解
更多Go相关内容:Go-Golang学习总结笔记
有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。