摘要
本文介绍了Go语言中字符串的特点,与java中的string进行了对比,最后介绍了Go中String与其他基本类型常用的相互转换方式。
1、go字符串概述
定义
字符串string在go中同样被定义为基本数据类型,类型关键字为string,其本质就是一个不能修改的字符数组。其常用定义方式有两种:
var str string = "hello"
str := "hello"
本质
go语言中string类型的本质与一个指向字符数组的切片类似,该类型大小固定为16个字节,其中8个字节表示一个指向字符数组的指针,另外8个字节表示字符串长度。可以验证如下:
var str1 string = "hello"
fmt.Printf("str1的类型是%T,\"%s\"变量本身占用%d个字节,字符串长度为%d\n", str1, str1, unsafe.Sizeof(str1), len(str1))
str2 := "hello撒大"
fmt.Printf("str2的类型是%T,\"%s\"变量本身占用%d个字节,字符串长度为%d\n", str2, str2, unsafe.Sizeof(str2), len(str2))
******结果*******
str1的类型是string,"hello"变量本身占用16个字节,字符串长度为5
str2的类型是string,"hello撒大"变量本身占用16个字节,字符串长度为11
2、与java的String异同之处
不同之处
- 1、java中String是对象,而go中string是基本数据类型
- 2、java中String对象不能通过数组方式直接索引每个字符,但golang可以,如:
str := "123"
fmt.Println(str[1])
*****输出*****
50 //go中字符byte默认通过无符号整形输出
相似之处
- java和go中的字符串都是满足不可变特性的
- java的不可变性体现在:用户不能通过对象引用直接修改对象本身,而通过jdk提供的方法如subString()等会返回新的对象,不会修改到对象本身。
- go的不可变性体现在:其不允许用户通过数组索引方式修改其指向的字符串数组,从而保证不可变性。
3、使用的注意事项
- 1、go中字符串类似于切片,因此也可以通过其衍生出更多的切片,但所有切片都不能修改字符数组,如案例:
var str string = "hello"
var strSlice = str[2:]
fmt.Println(strSlice[1:])
********输出*******
lo
- 2、go中字符串有两种表示形式:
- 通过双引号""标注,这种和java一模一样,会识别转义字符
- 通过反引号``标注,不识别转义字符,可用于源码展示等,同时还可以直接识别回车
4、string与其他基本类型的相互转换
基本数据类型转string
- 1、通过fmt.Sprint()函数转换,可以通过官方文档找到该函数的解释 %v:按照变量原有格式转换 http://www.golang.ltd/
- 2、通过strconv包下的FormatInt、ForMatFloat等函数转换,go语言不支持重载,FormatInt只对int64使用,有点麻烦,同时不支持字符的转换
//方式一
intNum := 25
var byteNum rune = 'c'
floatNum := 3.14159
fmt.Println(fmt.Sprintf("intNum的字符串为%v", intNum))
fmt.Println(fmt.Sprintf("byteNum的字符串为%c", byteNum))
fmt.Println(fmt.Sprintf("floatNum的字符串为%.3f", floatNum))
//方式二
fmt.Println("intNum的字符串为", strconv.FormatInt(int64(intNum), 10))
fmt.Println("floatNum的字符串为", strconv.FormatFloat(floatNum, 'f', -1, 64))
string转基本数据类型
- 通过strconv包下的ParseInt、ParseFloat等函数实现,如果不能转换则直接返回默认值
str5 := "true"
var num5 bool
num5, _ = strconv.ParseBool(str5)
fmt.Printf(str5+"代表的类型是%T\n", num5)
str6 := "hello" //不能转换则返回默认值
var num6 float64
num6, _ = strconv.ParseFloat(str6, 64)
fmt.Println(num6)
********输出*********
true代表的类型是bool
0
5、测试代码与输出
代码
package main
import (
"fmt"
"strconv"
"unsafe"
)
func main() {
// 1、string在go中被定义为基本数据类型,是一个字符数组,它本质上就是一个不能修改的数组
fmt.Println("**************************************************************************************************************")
fmt.Println("1、string在go中被定义为基本数据类型,其实是一个字符数组,其本质和切片类似,通过指针指向一个数组,区别在于不能修改该数组")
fmt.Println("因为字符串变量本身不表示字符串长度,其变量固定占16个字节,其数据结构应该是一个指针指向字符数组,然后一个int64表示长度")
fmt.Println("")
var str1 string = "hello"
fmt.Printf("str1的类型是%T,\"%s\"变量本身占用%d个字节,字符串长度为%d\n", str1, str1, unsafe.Sizeof(str1), len(str1))
str2 := "hello撒大"
fmt.Printf("str2的类型是%T,\"%s\"变量本身占用%d个字节,字符串长度为%d\n", str2, str2, unsafe.Sizeof(str2), len(str2))
var strSlice = str2[4:]
fmt.Println(strSlice[1:])
fmt.Println("")
// 2、string在go中是不可变的,这和java一致
// java中string不可变体现在字符串对象不会改变,通过string的subString方法等只会返回新的对象
// go中string不可变体现在不能通过字符数组赋值的方式修改字符串
fmt.Println("**************************************************************************************************************")
fmt.Println("2、string在go中是不可变的,这和java一致")
fmt.Println("java中string不可变体现在字符串对象不会改变,通过string的subString方法等只会返回新的对象")
fmt.Println("go中string不可变体现在不能通过字符数组赋值的方式修改字符串")
fmt.Println("")
str3 := str1
str3 = str2
// str3[0] = 'c';
fmt.Println("str3=", str3)
fmt.Println("")
// 3、字符串的两种表达形式
// 通过双引号""标注,这种和java一模一样,会识别转义字符
// 通过反引号``标注,不识别转义字符,可用于源码展示等,同时还可以直接识别回车
fmt.Println("**************************************************************************************************************")
fmt.Println("3、字符串的两种表达形式")
fmt.Println("通过双引号\"\"标注,这种和java一模一样,会识别转义字符")
fmt.Println("通过反引号``标注,不识别转义字符,可用于源码展示等,同时还可以直接识别回车")
fmt.Println("")
fmt.Printf("str4=\n")
fmt.Println(`str4=\n
`)
fmt.Println("")
// 4、string与其他基本类型的相互转换
// 基本数据类型转string
// 1、通过fmt.Sprint()函数转换,可以通过官方文档找到该函数的解释 %v:按照变量原有格式转换 http://www.golang.ltd/
// 2、通过strconv包下的FormatInt、ForMatFloat等函数转换,go语言不支持重载,FormatInt只对int64使用,有点麻烦,同时不支持字符的转换
// string转基本数据类型 通过strconv包下的ParseInt、ParseFloat等函数实现,如果不能转换则直接返回默认值
fmt.Println("**************************************************************************************************************")
fmt.Println("4、string与其他基本类型的相互转换")
fmt.Println("基本数据类型转string")
fmt.Println("1、通过fmt.Sprint()函数转换,可以通过官方文档找到该函数的解释 %V:按照变量原有格式转换 http://www.golang.ltd/")
fmt.Println("2、通过strconv包下的FormatInt、ForMatFloat等函数转换,go语言不支持重载,FormatInt只对int64使用,有点麻烦,同时不支持字符的转换")
fmt.Println("string转基本数据类型 通过strconv包下的ParseInt、ParseFloat等函数实现,如果不能转换则直接返回默认值")
fmt.Println("")
intNum := 25
var byteNum rune = 'c'
floatNum := 3.14159
fmt.Println(fmt.Sprintf("intNum的字符串为%v", intNum))
fmt.Println(fmt.Sprintf("byteNum的字符串为%c", byteNum))
fmt.Println(fmt.Sprintf("floatNum的字符串为%.3f", floatNum))
fmt.Println("intNum的字符串为", strconv.FormatInt(int64(intNum), 10))
fmt.Println("floatNum的字符串为", strconv.FormatFloat(floatNum, 'f', -1, 64))
str5 := "true"
var num5 bool
num5, _ = strconv.ParseBool(str5)
fmt.Printf(str5+"代表的类型是%T\n", num5)
str6 := "hello" //不能转换则返回默认值
var num6 float64
num6, _ = strconv.ParseFloat(str6, 64)
fmt.Println(num6)
}
输出
1、string在go中被定义为基本数据类型,其实是一个字符数组,其本质和切片类似,通过指针指向一个数组,区别在于不能修改该数组
因为字符串变量本身不表示字符串长度,其变量固定占16个字节,其数据结构应该是一个指针指向字符数组,然后一个int64表示长度
str1的类型是string,"hello"变量本身占用16个字节,字符串长度为5
str2的类型是string,"hello撒大"变量本身占用16个字节,字符串长度为11
撒大
2、string在go中是不可变的,这和java一致
java中string不可变体现在字符串对象不会改变,通过string的subString方法等只会返回新的对象
go中string不可变体现在不能通过字符数组赋值的方式修改字符串
str3= hello撒大
3、字符串的两种表达形式
通过双引号""标注,这种和java一模一样,会识别转义字符
通过反引号``标注,不识别转义字符,可用于源码展示等,同时还可以直接识别回车
str4=
str4=\n
4、string与其他基本类型的相互转换
基本数据类型转string
1、通过fmt.Sprint()函数转换,可以通过官方文档找到该函数的解释 %V:按照变量原有格式转换 http://www.golang.ltd/
2、通过strconv包下的FormatInt、ForMatFloat等函数转换,go语言不支持重载,FormatInt只对int64使用,有点麻烦,同时不支持字符的转换
string转基本数据类型 通过strconv包下的ParseInt、ParseFloat等函数实现,如果不能转换则直接返回默认值
intNum的字符串为25
byteNum的字符串为c
floatNum的字符串为3.142
intNum的字符串为 25
floatNum的字符串为 3.14159
true代表的类型是bool
0