03-Go语言基础之基本数据类型

Go整型

Go语言的数值类型包含不同大小的整数型、浮点数和负数,每种数值类型都有大小范围以及正负符号。

整型的使用

  1. golang整数类型分为有符号和无符号
  2. golang默认整型是int型

整型分为以下两个大类:

  • 按长度分为:int8、int16、int32、int64

  • 对应的无符号整型:uint8、uint16、uint32、uint64

  • uint8就是我们熟知的byte

类型 描述
uint8 无符号 8位整型 (0 到 255)
uint16 无符号 16位整型 (0 到 65535)
uint32 无符号 32位整型 (0 到 4294967295)
uint64 无符号 64位整型 (0 到 18446744073709551615)
int8 有符号 8位整型 (-128 到 127)
int16 有符号 16位整型 (-32768 到 32767)
int32 有符号 32位整型 (-2147483648 到 2147483647)
int64 有符号 64位整型 (-9223372036854775808 到 9223372036854775807)

不同整型用于存储不同场景的数据,了解即可。

特殊整型

类型 描述
uint 32位操作系统上就是uint32,64位操作系统上就是uint64
int 32位操作系统上就是int32,64位操作系统上就是int64
uintptr 无符号整型,用于存放一个指针

数字字面量语法(Number literals syntax)

Go1.13版本之后引入了数字字面量语法,这样便于开发者以二进制、八进制或十六进制浮点数的格式定义数字。
而且还允许我们用 _ 来分隔数字,比如说: v := 123_456 表示 v 的值等于 123456。

整型案例

package main

import "fmt"

func main() {
    // 默认根据你机器系统架构来,64为机器,就是int64
    var n1 = 100

    // n1的类型:int
    fmt.Printf("n1的类型:%T \n", n1)

    // 也可以指定整型类型,但是要注意赋值范围
    var n2 int8 = 127
    var n3 uint8 = 0
    var n4 int64 = -123456789

    // 一般开发,定义整型关心不到这些区别,了解即可
    // 127 0 -123456789
    fmt.Println(n2, n3, n4)

    // 还有一些额外的知识点,定义不同进制的整型语法 ,叫做数字字面量语法(Number literals syntax)
    // 便于开发者,定义二进制、八进制、十六进制等格式的数字,使用场景也较少,了解做笔记即可

    var (
        i1 = 10          // 十进制
        i2 = 0b1010      // 二进制
        i3 = 0xa         // 十六进制
        i4 = 1234_56_789 //支持数字里以_分割,看起来,例如银行里的余额 1,000元 看起来清晰
    )
    fmt.Println(i1, i2, i3, i4)

    // 也可以利用fmt的格式化打印,获取不同进制的结果
  // 格式化打印
    res1 := 10
    fmt.Println("该函数自带换行")
    fmt.Printf("十进制:%d \n", res1)
    fmt.Printf("二进制:%b \n", res1)
    fmt.Printf("八进制:%o \n", res1)
    fmt.Printf("十六进制:%x \n", res1)
}

Go浮点型

Go 语言提供了两种精度的浮点数,float32 和 float64,编译器默认声明为float64

小数类型就是存放小数的,如1.2 0.005 -2.32

注意,计算机的浮点数是不精准的,实际处理工作业务遇见浮点数运算一般都是转成整型后处理。

类型 占用存储空间 数值范围
单精度float32 4字节 -3.4e38~3.4e38
双精度float64 8字节 -1.8E308 ~ 1.8e308
package main

import (
    "fmt"
    "math"
)

func main() {
    var price float32 = 11.22 //正数符号
    fmt.Println("price=", price)
    var num1 float32 = -3.4 //负数符号
    var num2 float64 = -8.23
    fmt.Println("num1=", num1)
    fmt.Println("num2=", num2)

    //尾数可能丢失,精度缺损
    var num3 float32 = -123.11111111105 //精度丢失了
    var num4 float64 = -123.11111111105 //float64的精度高于float32
    fmt.Println("num3=", num3, "num4=", num4)
    //输出结果
    //num3= -123.111115 num4= -123.11111111105

    // 可以用math数学模块,打印浮点数看看
    fmt.Printf("%f\n", math.Pi)
    fmt.Printf("%.2f\n", math.Pi) // 保留2位小数
    fmt.Printf("%f\n", math.MaxFloat64)
    fmt.Printf("%f\n", math.MaxFloat32)
}

结果

➜  goStudy go run main.go
price= 11.22
num1= -3.4
num2= -8.23
num3= -123.111115 num4= -123.11111111105
3.141593
3.14
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000
340282346638528859811704183484516925440.000000

Go布尔型

一个布尔类型的值只有两种:true 和 false。

注意的是

  • if 和 for 语句的条件部分都是布尔类型的值,并且==和<等比较操作也会产生布尔型的值。
  • 布尔值变量默认值是false
  • Go语言不允许整型转布尔值,不同于其他语言。
  • 布尔值无法参与运算,也无法转换。
package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var t = true
    fmt.Println("t=", t)
    fmt.Println("t字节数=", unsafe.Sizeof(t))

    var f = false
    fmt.Println("f=", f)
    fmt.Println("f字节数=", unsafe.Sizeof(f))

    //默认布尔值
    var b bool
    fmt.Printf("变量b类型:%T,变量b值:%v\n", b, b)
}

/*
结果
t= true
t字节数= 1
f= false
f字节数= 1
变量b类型:bool,变量b值:false


*/

Go格式化输出fmt包语法

# 用于fmt.Printf()的格式化语法

# 通用:

%v    值的默认格式表示。当输出结构体时,扩展标志(%+v)会添加字段名
%#v    值的Go语法表示
%T    值的类型的Go语法表示
%%    百分号


布尔值:
%t    单词true或false


整数
%b    表示为二进制
%c    该值对应的unicode码值
%d    表示为十进制
%o    表示为八进制
%q    该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x    表示为十六进制,使用a-f
%X    表示为十六进制,使用A-F
%U    表示为Unicode格式:U+1234,等价于"U+%04X"

浮点数、复数
%b    无小数部分、二进制指数的科学计数法,如-123456p-78;参见strconv.FormatFloat
%e    科学计数法,如-1234.456e+78 
%E    科学计数法,如-1234.456E+78 
%f    有小数部分但无指数部分,如123.456 
%F    等价于%f %g    根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
%G    根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)

字符串、字符
%s    直接输出字符串或者[]byte
%q    该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
%x    每个字节用两字符十六进制数表示(使用a-f)
%X    每个字节用两字符十六进制数表示(使用A-F)

指针
%p    表示为十六进制,并加上前导的0x

Go字符串

字符串处理是任何一门语言的重点内容

  • Go字符串是一个不可改变的字节序列
  • Go字符串通常用来表示人类可阅读的文本数据
  • Go字符串默认编码使用UTF-8
  • Go字符串的值,必须是双引号www.yuchaoit.cn

字符串转义符

Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。

转义符 含义
\r 回车符(返回行首)
\n 换行符(直接跳到下一行的同列位置)
\t 制表符
\' 单引号
\" 双引号
\\ 反斜杠

字符串综合练习

package main

import "fmt"

func main() {
    // 声明字符串类型
    var story string = "努力学习是为了提升你的抗风险能力"
    fmt.Println(story)

    // 简短声明
    filename := "/var/log/nginx/access.log"
    fmt.Printf("filename类型:%T,filename值:%v\n", filename, filename)

    //Go字符串能识别特殊符号,可以使用转义符
    story2 := "妖怪\n还不快快放了我\"大哥\"!"
    fmt.Println(story2)

    // Go字符串里使用 反引号,以原生字符串形式输出,不解析任何特殊字符,防止如注入攻击等
    story3 := `那年我
双手插兜,
不知道什么叫做\n对手!`
    fmt.Println(story3)

    //Go字符串是不可修改的
    story4 := "hello world"
    //story4[1]='x'  错误,不允许修改
    fmt.Printf("第2个字符:%c\n", story4[1])

    // 数数字符串,有多少个字符(长度)
    // 一个中文占3个英文字母长度
    story5 := "hello world哈"
    fmt.Println("story5字符串长度:", len(story5))

    //Go字符串拼接
    s1 := "刘德华"
    s2 := "春节快乐"
    fmt.Println(s1 + "--" + s2)

    //按格式,格式化字符串且返回最终结果
    res := fmt.Sprintf("大家好,%s祝大家%s!", s1, s2)
    fmt.Println(res)

    //Go多行字符串拼接,注意结尾的+号
    s3 := "你" + "总该" + "为自己" +
        "想想未来" + "!"
    fmt.Println(s3)

    //Go for循环遍历字符串
    s4 := "helloWorld"
    for index, ret := range s4 {
        fmt.Printf("index---%v,ret--%c\n", index, ret)
    }

    // Go也能实现修改字符串,这里先不做了解,还需要学完slice切片类型
    myname := "hello world"
    m1 := []rune(myname) //转化为[]int32的切片,rune是int32的别名
    m1[4] = '皮'          //修改索引对应的值
    myname = string(m1)  //类型强转,rune转为string
    fmt.Println(myname)

}

/*

➜  goStudy go run main.go
努力学习是为了提升你的抗风险能力
filename类型:string,filename值:/var/log/nginx/access.log
妖怪
还不快快放了我"大哥"!
那年我
双手插兜,
不知道什么叫做\n对手!
第2个字符:e
story5字符串长度: 14
刘德华--春节快乐
大家好,刘德华祝大家春节快乐!
你总该为自己想想未来!
index---0,ret--h
index---1,ret--e
index---2,ret--l
index---3,ret--l
index---4,ret--o
index---5,ret--W
index---6,ret--o
index---7,ret--r
index---8,ret--l
index---9,ret--d
hell皮 world

*/

字符串处理strings包

https://pkg.go.dev/strings 官网教程

一个内置的提供了对字符串诸多功能处理的包,有很多函数可用。

package main

import (
    "fmt"
    "strings"
)

func main() {
    url1 := "http://www.yuchaoit.cn"

    //判断字符串是否以xx开头,返回布尔值
    res := strings.HasPrefix(url1, "https://")
    res2 := strings.HasPrefix(url1, "http://")
    fmt.Println("该url复合https吗?", res)
    fmt.Println("该url符合http吗?", res2)

    //判断字符串是否以xx结尾
    url2 := "http://www.yuchaoit.cn/login"
    res3 := strings.HasSuffix(url2, "home")
    res4 := strings.HasSuffix(url2, "login")
    fmt.Println("url2是home接口", res3)
    fmt.Println("url2是login接口", res4)

    //判断字符在字符串中首次出现的索引位置,没有返回-1
    s1 := "   hello world and code!"
    res5 := strings.Index(s1, "o") // 索引号是4
    res6 := strings.Index(s1, "x") //找不到返回-1
    fmt.Printf("res5 is %v\n", res5)
    fmt.Printf("res6 is %v\n", res6)

    //返回字符最后一次出现的索引位置,没有返回-1
    res7 := strings.LastIndex(s1, "o")
    res8 := strings.LastIndex(s1, "x")
    fmt.Printf("res7 is %v\n", res7)
    fmt.Printf("res8 is %v\n", res8)

    //字符串替换
    res9 := strings.Replace(s1, "world", "golang", 2)
    res10 := strings.Replace(s1, "world", "golang", 1)
    //语法,strings.Replace("原字符串", "被替换的内容", "替换的内容", 替换次数)
    //原字符串中有2个world,才能替换2次
    fmt.Printf("res9 is %v\n", res9)
    fmt.Printf("res10 is %v\n", res10)

    //求字符在字符串中出现的次数,不存在返回0次
    countTime0 := strings.Count(s1, "h")
    countTime1 := strings.Count(s1, "l")
    fmt.Printf("字符h出现次数: %v\n", countTime0)
    fmt.Printf("字符l出现次数: %v\n", countTime1)

    //重复几次字符串
    res11 := strings.Repeat(s1, 0)
    res12 := strings.Repeat(s1, 1)
    res13 := strings.Repeat(s1, 2)
    // strings.Repeat("原字符串", 重复次数)
    fmt.Printf("res11 is :%v\n", res11)
    fmt.Printf("res12 is :%v\n", res12)
    fmt.Printf("res13 is :%v\n", res13)

    //字符串全部大写,如验证码校验
    res14 := strings.ToUpper(s1)
    fmt.Printf("res14 is : %v\n", res14)

    //字符串改小写
    res15 := strings.ToLower(s1)
    fmt.Printf("res15 is: %v\n", res15)

    //去除首尾的空格,如去除用户表单提交的数据
    res16 := strings.TrimSpace(s1)
    fmt.Printf("res16 is :%v\n", res16)

    //去除首尾指定的字符
    // 在前一题,去除空格基础上再操作
    res17 := strings.Trim(res16, "he") //删除头尾的h、e 字符
    fmt.Printf("res17 is: %v\n", res17)

    //去除开头指定的字符
    res18 := strings.TrimLeft(res16, "he")
    fmt.Printf("res18 is %v\n", res18)

    //去除结尾指定的字符
    res19 := strings.TrimRight(s1, "!")
    fmt.Printf("res19 is %v\n", res19)

    //用指定的字符串将string类型的切片元素结合
    str1 := []string{"hello", "world", "hello", "golang"}
    fmt.Println(str1)                // [hello world hello golang]
    res20 := strings.Join(str1, ",") //返回值是字符串
    fmt.Printf("res20 is %v, 类型:%T\n", res20, res20)
}

/*

该url复合https吗? false
该url符合http吗? true
url2是home接口 false
url2是login接口 true
res5 is 7
res6 is -1
res7 is 20
res8 is -1
res9 is    hello golang and code!
res10 is    hello golang and code!
字符h出现次数: 1
字符l出现次数: 3
res11 is :
res12 is :   hello world and code!
res13 is :   hello world and code!   hello world and code!
res14 is :    HELLO WORLD AND CODE!
res15 is:    hello world and code!
res16 is :hello world and code!
res17 is: llo world and code!
res18 is llo world and code!
res19 is    hello world and code
[hello world hello golang]
res20 is hello,world,hello,golang, 类型:string

*/

Go字符

ascii码表

ASCII码表

Go字符如何表示

image-20221221154821017

"你好,我是go语言"

这个字符串是由挨个的'字符'组成,我们可以for遍历字符串,得到单个的字符
字符在go语言里用单引号包裹,如 '你'

Go语言表示字符有两个方式
1. uint8类型,也叫做byte类型,代表一个ASCII码字符,  uint8整数范围0~255

2. rune类型,代表一个UTF-8编码字符 ,而int32可表示的字符就多了,  毕竟范围-2147483648 到 2147483647
一般要处理中文,日文等复杂字符时,就用到了rune类型

3.UTF-8编码表下的中文汉字,是由3~4个字节组成,因此for遍历中文字符串,需要额外处理。

4.Go字符串底层是用 []byte数组存储。

Go字符实践

package main

import "fmt"

func main() {
    // 默认都用int32去存字符了,也就是rune类型,因为go默认编码是utf-8
    var a = 'y'
    var b = 'c'
    var c = '于'
    fmt.Printf("a 类型:%T,值:%c\n", a, a)
    fmt.Printf("b 类型:%T,值:%c\n", b, b)
    fmt.Printf("c 类型:%T,值:%c\n", c, c)

    //也可以自己去指定 byte类型,也就是uint8
    var c1 byte = 'a'
    var c2 byte = '2'
    //直接输出byte的值,也就是输出对应的字符的ascii码值
    fmt.Println("c1=", c1)
    fmt.Println("c2=", c2)

    //输出字符的值,需要格式化输出
    fmt.Printf("c1值=%c  c1类型=%T\n", c1, c1)
    fmt.Printf("c2值=%c  c1类型=%T\n", c2, c2)
}

/*
a 类型:int32,值:y
b 类型:int32,值:c
c 类型:int32,值:于
c1= 97
c2= 50
c1值=a  c1类型=uint8
c2值=2  c1类型=uint8

*/

Go字符串如何修改

img

字符串底层是一个byte数组,所以可以和[]byte类型相互转换。

字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。

rune类型用来表示utf-8字符,一个rune字符由一个或多个byte组成。

修改中文字符串

package main

import "fmt"

func main() {
    hobby := "书中自有黄金屋"
    //先进行类型强转,字符串可以直接转成 []byte 或者 []rune  前提看你转的是中文,还是英文

    runeHobby := []rune(hobby)
    // []int32,值 [20070 20013 33258 26377 40644 37329 23627] 里面的数字就是对应的utf-8编码表的值
    fmt.Printf("runeHobby类型:%T,值%v\n", runeHobby, runeHobby)
    //数组是可以修改的,如
    runeHobby[0] = '梦'
    fmt.Printf("修改后runeHobby类型:%T,值%v\n", runeHobby, runeHobby)

    // []rune 再转为 string类型
    hobby = string(runeHobby)
    fmt.Printf("新字符串hobby类型:%T,%v\n", hobby, hobby)

}

修改英文字符串

package main

import "fmt"

func main() {
    hobby := "helloworld"
    //先进行类型强转,字符串可以直接转成 []byte 或者 []rune  前提看你转的是中文,还是英文

    byteHobby := []byte(hobby)
    fmt.Printf("byteHobby类型:%T,值%v\n", byteHobby, byteHobby)
    //数组是可以修改的,如
    byteHobby[0] = 'H'
    fmt.Printf("修改后byteHobby类型:%T,值%v\n", byteHobby, byteHobby)

    // []rune 再转为 string类型
    hobby = string(byteHobby)
    fmt.Printf("新字符串hobby类型:%T,%v\n", hobby, hobby)

}

/*
byteHobby类型:[]uint8,值[104 101 108 108 111 119 111 114 108 100]
修改后byteHobby类型:[]uint8,值[72 101 108 108 111 119 111 114 108 100]
新字符串hobby类型:string,Helloworld

*/

Go类型转换

Golang在不同的数据类型之间赋值时需要显示转化,无法自动转换(没有隐式类型转换)。

并且只能在两个类型允许相互转换时使用。

语法

T(v)  将v转化为T类型

T  数据类型 如 int32 int64 float32

V  需转化的变量

类型转化注意点

1)Go中数据类型的转换可以从 数值范围大 > 数值范围小,反之也可,注意别溢出

2)被转化的变量存储的数值,变量本身的数据类型没变化

package main

import "fmt"

func main() {
    var num1 int32 = 100
    var num2 float32 = float32(num1)                             //num2强转为浮点型
    fmt.Printf("num1=%v  num2=%v num2类型:%T\n", num1, num2, num2) //%v 值的默认格式
    fmt.Printf("num1类型是:%T", num1)                               //本身的类型 没有变化
}

/*
num1=100  num2=100 num2类型:float32
num1类型是:int32
*/

不同类型变量如何计算

package main

import "fmt"

func main() {
    var n1 int32 = 12
    var n2 int64 = 10

    //n3:=n1+n2 //不同类型之间无法计算,需要强转
    n3 := n1 + int32(n2)
    fmt.Println(n3) // 结果 22
}

Go基本数据类型转string

字符串类型是开发过程用的最多的类型,也经常会与其他数据类型转换。

fmt.Sprintf

  • 语法:fmt.Sprintf("%参数",表达式)

  • 该函数返回值是string

  • Sprintf 根据格式说明符格式化并返回结果字符串。

package main

import "fmt"

func main() {
    var num1 int = 66
    var num2 float64 = 25.25
    var b bool = true
    var myChar byte = 'c'

    //%q 该值对应的双引号括起来的Go语法字符串字面值,必要时会采用安全的转义表示
    //%d 表示为十进制
    // Sprintf 根据格式说明符格式化并返回结果字符串。
    str1 := fmt.Sprintf("%d", num1)
    fmt.Printf("str1 type %T str=%q\n", str1, str1)

    //%f 有小数点
    str2 := fmt.Sprintf("%f", num2)
    fmt.Printf("str2 type %T str2=%q\n", str2, str2)

    //%t 布尔值
    str3 := fmt.Sprintf("%t", b)
    fmt.Printf("str3 type %T str3=%q\n", str3, str3)

    //%c Unicode码对应的字符
    str4 := fmt.Sprintf("%c", myChar)
    fmt.Printf("str4 type %T str4=%q\n", str4, str4)
}

strconv包

https://pkg.go.dev/strconv

包 strconv 实现了与基本数据类型的字符串表示之间的转换。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var num1 int = 99
    var num2 float64 = 66.66
    var b1 bool = true

    str1 := strconv.FormatInt(int64(num1), 10)
    fmt.Printf("str1类型是%T str1=%q\n", str1, str1)

    //参数解释
    // f 格式
    // 4 小数位保留4位
    // 64  表示float64
    str2 := strconv.FormatFloat(num2, 'f', 4, 64)
    fmt.Printf("str2类型是%T str2=%q\n", str2, str2)

    str3 := strconv.FormatBool(b1)
    fmt.Printf("str3类型是%T str3=%q\n", str3, str3)

    //Itoa,将int转为string,注意,必须是int类型
    var num3 int32 = 1123
    str4 := strconv.Itoa(int(num3)) //必须强转int()
    fmt.Printf("str4类型是%T str4=%q\n", str4, str4)

}
Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2022-12-22 13:54:42

results matching ""

    No results matching ""