四、基础语法
4.1、注释
注释就是对代码的解释和说明,其目的是让人们能够更加轻松地了解代码。注释是开发人员一个非常重要的习惯,也是专业的一种表现。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。
注释只是为了提高可读性,不会被计算机编译。
4.2、变量
在计算机编程中,我们用变量来保存并管理很多数据,并用变量名来区分、识别和处理这些数据。
变量本质上是一种对内存地址的引用,让你能够把程序中准备使用的每一段数据都赋给一个简短、易于记忆的名字进行操作。
4.2.1、声明变量
和C语言一样,Go语言也是通过var关键字进行声明,不同的是变量名放在类型前,具体格式如下
var 变量名 变量类型
声明未赋值,系统默认赋这些类型零值
如果声明多个变量,可以进行简写
package main
import "fmt"
// 全局变量: 定义在函数外的变量
var n7 = 100
var n8 = 9.7
// 设计者认为上面的全局变量的写法太麻烦了,可以一次声明:
var (
n9 = "summer"
n10 = 21
)
func main() {
// 定义在{}中的变量叫: 局部变量
// 第一中变量,变量的使用方式:指定变量的类型,并复制,
var num int = 20
fmt.Println(num)
//第二种: 指定变量的类型,但是不复制,使用默认值
var num2 int
fmt.Println(num2)
// 第三种,如果没有写变量的类型,那么根据后面额值践行判定变量的类型,(自定类型推断)
var num3 = "tom"
fmt.Println(num3)
// 第四种: 省略vat, 注意 := 不能写为=
sex := "男"
fmt.Println(sex)
// 支持一次性声明多个变量(多变量声明)
// 声明多个变量
var n1, n2, n3 int
fmt.Println(n1)
fmt.Println(n2)
fmt.Println(n3)
var n4, name, n5 = 10, "jack", 7.8
fmt.Println(n4)
fmt.Println(name)
fmt.Println(n5)
n6, height := 6.9, 100.6
fmt.Println(n6)
fmt.Println(height)
fmt.Println(n7)
fmt.Println(n8)
fmt.Println(n9)
fmt.Println(n10)
}
4.2.2、变量赋值
变量赋值的3种方法
(1)变量名=值
// 先声明再赋值
var x int
x = 10 // 不要 重复声明 : var x = 10
fmt.Println(x)
x = 20. // 重新赋值
// 直接声明赋值
// var y string= "hello yuan!"
var y = "hello yuan!"
fmt.Println(y)
// 声明赋值精简版
s := "hi,yuan!" // 1、编译器会自动根据右值类型推断出左值的对应类型,等同于var s = "hi,yuan!"。2、该变量之前不能声明,否则重复声明
fmt.Println(s)
// 一行声明赋值多个变量
var name,age = "yuan",22
(2)变量名=变量名
var a = 100
var b = a // 变量之间的赋值是值拷贝
fmt.Println(a, b)
a = 200
fmt.Println(b)
3)变量名=值 + 值 (变量名)
var a, b = 10, 20
var c = a + b
fmt.Println(c)
var d = c + 100
fmt.Println(d)
4.2.3、匿名变量
匿名变量及没有命名的变量,在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量(anonymous variable) 匿名变量用一个下划线_
表示
a,b,c :=4,5,6
fmt.Println(a,b,c)
// 如果只想接受第个变量,可以对前两个变量匿名
_,_,x := 4,5,6
fmt.Println(x)
匿名变量不占用命名空间,不会分配内存
让代码非常清晰,基本上屏蔽掉了可能混淆代码阅读者视线的内容,从而大幅降低沟通的复杂度和代码维护的难度。
4.2.4、变量命名规则
变量命名是需要遵循一定的语法规范的,否则编译器不会通过。
1、变量名称必须由数字、字母、下划线组成。
2、标识符开头不能是数字。
3、标识符不能是保留字和关键字。
4、建议使用驼峰式命名,当名字有几个单词组成的时优先使用大小写分隔
5、变量名尽量做到见名知意。
6、变量命名区分大小写
package main
import "fmt"
func main() {
var 年龄 int = 19
fmt.Println(年龄)
}
/*
什么事标识符?
变量,方法等只要是起名字的地方,那个名字就是标识符 var age int = 19 var price float64 = 9.8
标识符定义规则:
1、三个都可以(组成部分): 数字,字母、下划线_
不建议使用,建议使用字母:46字母
2.四个注意,不可以以数字开头,严格区分大小写,不能包含空格,不可以使用Go中保留关键字
3.见名之意: 增强可读性
4.下划线"_" 本身在Go中是一个特殊的标识符,称为空标识符。可以代表其任何的标识符,但是它对应的值会被忽略(比如: 忽略某个返回值,)所以仅能被作为占位符使用,
不能单独作为标识符使用
5.可以用如下形式,但不建议: var int int = 10 (int,float32,float64等不算是保留关键字,但是也尽量不要使用)
6.长度无限制,但是不建议太长,asdasdasasdasdadadadadadfasdfcas
7.起包规则
(1)包名:尽量保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库冲突
(1、)为什么之前在定义源文件的时候,一般我们都用package main 包
main包是一个程序的入口包,所有你main函数它所在的包建议定义为main包,入彀不定义为main包,那么就不能得到可执行文件。
(2)变量名,函数名、常量名: 采用驼峰法。就是单词按照大写区分。
var stuNameDetail string = 'summer'
(3.) 如果变量名,函数名,常量名字首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本报中使用
(利用首字母大、小写完成权限控制)
注意: import导入语句通常放在文件开头包声明语句的下面。导入的包名需要使用双引号包裹起来。
包名是从$GOPATH/src/后开始计算的,使用/进行路径分隔。
*/
go语言中有25个关键字,不能用于自定义变量名
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
还有30多个预定义的名字,用于内建的常量、类型和函数
// 内建常量:
true false iota nil
// 内建类型:
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
// 内建函数:
make len cap new append copy close delete
complex real imag
panic recover
4.3、语句分隔符
就像我们写作文一样,一定要有像逗号或者句号这样的语句分隔符,否则无法断句根本不能理解,编程语言也一样,需要给解释器或者编译器一个语句分割,让它知道哪里到哪里是一个语句,才能再去解析语句。
在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分(不建议这样写)。
//var name = "yuan";var age = 18 // 不推荐
//fmt.Println(name)
//fmt.Println(age) // 不报错但是不推荐
// 推荐写法
var name = "yuan" // 换行即分隔符
var age = 18
fmt.Println(name)
fmt.Println(age)
4.4、基本数据类型
基本数据类型包含整型和浮点型,布尔类型以及字符串,这几种数据类型在几乎所有编程语言中都支持。
4.4.1、整形
字节了解:
字节(Byte):计算机中数据储存的单位。
位(bit):也叫作“比特”,计算机中数据储存的最小单位,因为在计算机中是以二进制的形式数据储存,所以每个位以“0”或“1”表示。
位和字节的关系是:8个位组成一个字节。
字节与位的关系:1Byte=8bit。
- 整形类型
具体类型 | 取值范围 |
---|---|
int8 | -128到127 |
uint8 | 0到255 |
int16 | -32768到32767 |
uint16 | 0到65535 |
int32 | -2147483648到2147483647 |
uint32 | 0到4294967295 |
int64 | -9223372036854775808到9223372036854775807 |
uint64 | 0到18446744073709551615 |
uint | 与平台相关,32位操作系统上就是uint32 ,64位操作系统上就是uint64 |
int | 与平台相关,32位操作系统上就是int32 ,64位操作系统上就是int64 |
var x int
x = 9223372036854775809
fmt.Print(x) // overflows int
package main
import (
"fmt"
"unsafe"
)
func main() {
// 定一个整数类型
var num1 int8 = 20
fmt.Println(num1)
var num2 int8 = 10
fmt.Println(num2)
var num3 = 28
// Pintf函数的作用就是: 格式化的,把num3的类型 填充到%T的位置上
fmt.Printf("mum3的类型是: %T", num3) //mum3的类型是: int
//变量占用的字节数
fmt.Println()
fmt.Println(unsafe.Sizeof(num3))
}
- 进制转换
// 十进制转化
var a int = 10
fmt.Printf("%d \n", a) // 10 占位符%d表示十进制
fmt.Printf("%b \n", a) // 1010 占位符%b表示二进制
fmt.Printf("%o \n", a) // 12 占位符%o表示八进制
fmt.Printf("%x \n", a) // a 占位符%x表示十六进制
// 八进制转化
var b int = 020
fmt.Printf("%o \n", b) // 20
fmt.Printf("%d \n", b) // 16
fmt.Printf("%x \n", b) // 10
fmt.Printf("%b \n", b) // 10000
// 十六进制转化
var c = 0x12
fmt.Printf("%d \n", c) // 18
fmt.Printf("%o \n", c) // 22
fmt.Printf("%x \n", c) // 12
fmt.Printf("%b \n", c) // 10010
4.4.2、浮点型
- float类型
float类型分为float32
和float64
两种类型,这两种浮点型数据格式遵循 IEEE 754 标准。
单精度浮点数占用4个字节(32位)存储空间来存储一个浮点数。而双精度浮点数使用 8个字节(64位)存储空间来存储一个浮点数。
单精度浮点数最多有7位十进制有效数字,如果某个数的有效数字位数超过7位,当把它定义为单精度变量时,超出的部分会自动四舍五入。双精度浮点数可以表示十进制的15或16位有效数字,超出的部分也会自动四舍五入。
浮点类型默认声明为float64。
package main
import "fmt"
func main() {
// 定义浮点类型的数据:
var num1 float32 = 3.14
fmt.Println(num1)
// 可以表示在正浮点数,也可以表示服浮点数
var num2 float32 = -3.14
fmt.Println(num2)
//浮点数可以用十进制表示形式,也可以用科学技术法表示形式,E大小写都可以的
var num3 float32 = 314e-2
fmt.Println(num3)
var num4 float32 = 314e+2
fmt.Println(num4)
var num5 float32 = 314e+2
fmt.Println(num5)
var num6 float32 = 314e+2
fmt.Println(num6)
// 浮点数可能会有精度消失的损失,所以通常情况下。建议你使用:float64
var num7 float32 = 356.000000916
fmt.Println(num7)
var num8 float64 = 356.000000916
fmt.Println(num8)
// golang 中默认的浮点类型为: float64
var num9 = 3.17
fmt.Printf("num9对应的默认类型为:%T", num9) //num9对应的默认类型为:float64
}
- 科学计数表示
var f1 = 2e10 // 即使是整数用科学技术表示也是浮点型
fmt.Println(f1,reflect.TypeOf(f1))
var f2 = 2e-2
fmt.Println(f2,reflect.TypeOf(f2))
字符编码
package main
import "fmt"
func main() {
// 定义字符类型的数据
var c1 byte = 'a' // 97
fmt.Println(c1)
var c2 byte = '6' // 54
fmt.Println(c2)
var c3 byte = '(' //40
fmt.Println(c3)
/* 字符类型,本质上就是一个整数,也可以直接参与计算,输出字符的时候,会将对应的码值做一个输出
字母,数字,标点等字体,底层是按照ASCII进行存储。
*/
var c4 int = '中'
fmt.Println(c4)
/*
汉子字符,底层对应的是Unicode码值
对应的码值为20013,byte类型溢出,能存储的范围,可以用int
总结:Golang的字符集对应的使用是UTf-8编码,(Unicode是对应的字符集,UTF-8是Unicode的其中的一种编码方案)
*/
var c5 byte = 'A'
//想显示对应的字符,必须采用格式化输出
fmt.Printf("c5对应的具体字符为:%c", c5) //c5对应的具体字符为:A
}
4.4.3、布尔类型
布尔是最基本数据类型之一,只有两个值,True和false,分别代表逻辑判断中的真和假,主要应用在条件判断中。
package main
import (
"fmt"
"reflect"
)
func main() {
var b bool
b = true //声明b是一个布尔类型
b = false // 该类型只有true和false两个值,分别代表真假两种状态
fmt.Println(b, reflect.TypeOf(b))
fmt.Println(1 == 1) // 比较运算符的结构是一个布尔值
// // fmt.Println(1 == "1") // 报错,mismatched types不能比较
fmt.Println(3 > 1)
var name = "hao"
var b2 = name == "summer"
fmt.Println(b2)
}
4.4.4、字符串
字符串是最基本也是最创建的数据类型,是通过双引号将多个字符按串联起来的一种数据,用于展示文本
var = "hello wolrd"
单引号只能标识字符
字符串的基本操作
package main
import "fmt"
func main() {
//1. 定义一个字符串
var s1 string = "你好全面拥抱golang"
fmt.Println(s1)
// 2.字符串是不可以变的: 指的是字符串一旦定义好,其中的字符的值不能改变
var s2 string = "abc"
//s2[0] = 't'
fmt.Println(s2)
// 字符串的拼接
var s5 string = "abc" + "def"
s5 += "hijk"
fmt.Println(s5)
// 当一个字符串过长的时候: 注意 + 保留在上一行的最后
var s6 string = "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" + "def" +
"abc" + "def"
fmt.Println(s6)
}
字符串在内存中是一段连续存储空间
注意:
- 索引从零开始计数
- go语言不支持负索引
var s = "hello yuan"
fmt.Println(s)
// (1)索引取值 slice[index]
a:= s[2]
fmt.Println(string(a))
// (2)切片取值slice[start:end], 取出的元素数量为:结束位置 - 开始位置;
b1:=s[2:5] //
fmt.Println(b1)
b2:=s[0:] // 当缺省结束位置时,表示从开始位置到整个连续区域末尾;
fmt.Println(b2)
b3:=s[:8] // 当缺省开始位置时,表示从连续区域开头到结束位置;
fmt.Println(b3)
// (3)字符串拼接
var s1 = "hello"
var s2 = "yuan"
var s3 = s1 + s2 // 生成一个新的字符串
fmt.Println(s3)
转义符
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。
转义符 | 含义 |
---|---|
\r |
回车符(返回行首) |
\n |
换行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\' |
单引号 |
\" |
双引号 |
\\ |
反斜杠 |
举个例子,我们要打印一个Windows平台下的一个文件路径:
package main
import "fmt"
func main() {
var s1 = "hello \nsummer"
fmt.Println(s1)
var s2 = "his namme is junue"
fmt.Println(s2)
var s3 = "D:\\next\\go.exe"
fmt.Println(s3)
}
多行字符串
Go语言中要定义一个多行字符串是,就必须使用反引号
字符:
package main
import "fmt"
func main() {
/*
3.字符串的表示形式
(1.)如果字符串中没有特殊符号,字符串的表示形式用双引号
(2.)如果字符串有特殊字符,字符串的表示形式用反引号 ``
*/
var s4 string = `package main
import (
"fmt"
"reflect"
)
func main() {
var b bool
b = true //声明b是一个布尔类型
b = false // 该类型只有true和false两个值,分别代表真假两种状态
fmt.Println(b, reflect.TypeOf(b))
fmt.Println(1 == 1) // 比较运算符的结构是一个布尔值
// // fmt.Println(1 == "1") // 报错,mismatched types不能比较
fmt.Println(3 > 1)
var name = "hao"
var b2 = name == "summer"
fmt.Println(b2)
}`
fmt.Println(s4)
}
反引号间换行将被作为字符串的换行,但是所有的转移符均无效,文本将会被原样输出。
基本数据类型之间的转换
package main
import "fmt"
func main() {
/*
Go在不同类型的变量之间赋值时,需要显示转换,并且只有显示转换(强制转换)
语法:
表达式T(v)将值v转换为类型T
T: 就是数据类型
V:就是需要转换的变量
*/
// 进行类型转换:
var n1 int = 100
// var n2 float32 = n1 在这里自动转换不好使 ,比如显示转换
fmt.Println(n1)
//fmt.Println(n2)
var n2 float32 = float32(n1)
fmt.Println(n2)
// 注意: n1的类型其实还是int类型,只是讲n1的值100转为了float32而已,n1还是int的类型
fmt.Printf("%T", n1) //int
fmt.Println()
// 将int64转为int8的时候,编译不会出错的,但是会数据的溢出
var n3 int64 = 888888
var n4 int8 = int8(n3)
fmt.Println(n4) // 56
var n5 int32 = 12
var n6 int64 = int64(n5) + 30 //一定要匹配=左右两边的数据类型
fmt.Println(n5)
fmt.Println(n6)
var n7 int64 = 12
var n8 int8 = int8(n7) + 127 // 编译通过,但是结果可能会溢出
//var n9 int8 = int8(n7) + 128 //编译不会通过
fmt.Println(n8)
//fmt.Println(n9)
}
基本数据类型转换为string
package main
import "fmt"
func main() {
var n1 int = 19
var n2 float32 = 4.78
var n3 bool = false
var n4 byte = 'a'
var s1 string = fmt.Sprint("%d", n1)
fmt.Printf("s1对应的类型是:%T, s1 = %q\n", s1, s1)
var s2 string = fmt.Sprint("%q \n", n2)
fmt.Printf("s1对应的类型是:%T, s1 = %q\n", s2, s2)
var s3 string = fmt.Sprint("%q \n", n3)
fmt.Printf("s1对应的类型是:%T, s1 = %q\n", s3, s3)
var s4 string = fmt.Sprint("%q \n", n4)
fmt.Printf("s1对应的类型是:%T, s1 = %q\n", s4, s4)
}
package main
import (
"fmt"
"strconv"
)
/*
1.基本数据类型和string的转换介绍
在程序开发中,我们经常需要讲基本数据类型转换成string类型,或者将string类型转成基本数据类型。
2.基本类型,string类型
方式一: fmt.Sprinlf("%参数",表达式) 重点练习 推荐方式
方式二: 使用strconv包的函数
*/
func main() {
var n1 int = 19
var s1 string = strconv.FormatInt(int64(n1), 10) // 参数: 第一个参数必须转为int64类型,第二个参数指定字面值的进制形式为十进制
fmt.Println("对应的类型是: %T, s1 = %q \n", s1, s1)
var n2 float64 = 4.29
var s2 string = strconv.FormatFloat(n2, 'f', 9, 64)
// 第二个参数: 'f' (-ddd.ddd) 第二个参数:9保留小数点后面9位 第四个参数: 表示这个小数是float64类型
fmt.Printf("对应的类型是: %T ,s2 = %q \n", s2, s2)
var n3 bool = true
var s3 string = strconv.FormatBool(n3)
fmt.Printf("对应的类型是: %T ,s3 = %q \n", s3, s3)
}
package main
import (
"fmt"
"strconv"
)
func main() {
// string 转换为 bool
var s1 string = "true"
var b bool
/* Parsebool这个函数的返回值有两个,(value bool ,err error)
value 就是我们得到的布尔值类型的数据,error出现的错误
我们只关注得到的布尔类型的数据,err可用用 _直接忽略
*/
b, _ = strconv.ParseBool(s1)
fmt.Printf("b的类型是: %T,b=%v \n", b, b)
// string 转换为 int64
var s2 string = "19"
var num1 int64
num1, _ = strconv.ParseInt(s2, 10, 64)
fmt.Printf("b的类型是: %T,num1=%v \n", num1, num1)
//string 转换为float32/float64
var s3 string = "3.145"
var f1 float64
f1, _ = strconv.ParseFloat(s3, 64)
fmt.Printf("b的类型是: %T,f1=%v \n", f1, f1)
// 注意 string向基本数据类型转换的时候,一定要确保string类型能够转换成有效的数据类型,否则最后得到的结果就是按照对应的类型的默认值输出
var s4 string = "golang"
var b1 bool
b1, _ = strconv.ParseBool(s4)
fmt.Printf("b的类型是: %T,f1=%v \n", b1, b1)
var s5 string = "golang"
var num2 int64
num2, _ = strconv.ParseInt(s5, 10, 64)
fmt.Printf("b的类型是: %T,f1=%v \n", num2, num2)
}
指针的基本与使用
package main
import "fmt"
func main() {
var age int = 18
// & 符号+ 变量 就可以获取这个变量内存的地址
fmt.Println(&age) //0xc0000b2008
// 定一个一个指针变量
// var代表要声明一个变量
// ptr 指针变量的名字
// ptr 对应的类型是: *int 是一个指针类型,(可以理解为,只想int类型的指针)
// &age就是一个地址, 是ptr变量的具体的值
var ptr *int = &age
fmt.Println(ptr)
fmt.Println("ptr本身这个存储空间的地址为:", &ptr)
// 想获取ptr这个指针或这个地址指向的哪个数据:
fmt.Println("ptr指向数值为:%v", *ptr) // ptr指向数值为:%v 18
/*
总结:最重要的就是两个符号
1.& 取内存地址
2. * 根据地址取值
*/
}
指针的4个细节
1.可以通过指针改变指向值。
2.指针变量接收的一定是地址值。
3.指针变量的地址不可以不匹配
4.基本数据类型(又叫值类型),都有对应的指针类型,形式为*数据类型,比如int的对应的指针就是*int,float32对应的指针类型就是*float。依次类推
字符串的常用方法
方法 | 介绍 |
---|---|
len(str) |
求长度 |
strings.ToUpper ,strings.ToLower |
生成一个新的全部大写的字符串,生成一个新的全部小写的字符串 |
strings.ReplaceAll |
生成一个新的原字符串被指定替换后的字符串 |
strings.Contains |
判断是否包含 |
strings.HasPrefix,strings.HasSuffix |
前缀/后缀判断 |
strings.Trim 、 |
去除字符串两端匹配的内容 |
strings.Index(),strings.LastIndex() |
子串出现的位置 |
strings.Split |
分割,将字符串按指定的内容分割成数组 |
strings.Join(a[]string, sep string) |
join操作,将数组按指定的内容拼接成字符串 |
package main
import (
"fmt"
"reflect"
"strings"
)
func main() {
s := "hello world"
// fmt.Println(len(s))
// strings.ToUpper 和 strings.ToLower
s1 := strings.ToUpper("Yuan")
s2 := strings.ToLower("Rain")
fmt.Println(s1, s2)
// strings.Trim
user := " yuan "
fmt.Println(len(user))
fmt.Println(strings.TrimLeft(user, " "))
fmt.Println(strings.TrimSpace(user))
fmt.Println(strings.Trim(user, " "))
s := "alvin,yuan,eric"
// strings.Index,strings.LastIndex
var index = strings.Index(s, "yuan!")
fmt.Println(index) // 未找到返回-1
var index2 = strings.LastIndex(s, "l")
fmt.Println(index2)
// strings.HasPrefix,strings.HasSuffix,strings.Contains(实现的依赖的就是strings.Index)
fmt.Println(strings.HasPrefix(s, "alv"))
fmt.Println(strings.HasSuffix(s, "eric"))
fmt.Println(strings.Contains(s, "eric"))
// strings.Split: 将字符串分割成数组
var ret2 = strings.Split(s, ",")
fmt.Println(ret2, reflect.TypeOf(ret2))
// strings.Join:将数组拼接成字符串
var ret3 = strings.Join(ret2, "-")
fmt.Println(ret3, reflect.TypeOf(ret3))
}
4.4.6、类型转换
Go语言中只有强类型转换,没有隐式类型转换,改语法只能在两个类型之间支持想换转换的时候使用。
// (1)整型之间的转换
var a int8
a = 99
fmt.Println(int64(a), reflect.TypeOf(int64(a)))
fmt.Println(float64(a), reflect.TypeOf(float64(a)))
// (2)string与int类型的转换
x := strconv.Itoa(98)
fmt.Println(x, reflect.TypeOf(x))
y, _ := strconv.Atoi("97")
fmt.Println(y, reflect.TypeOf(y))
// (3) Parse系列函数
// ParseInt
// 输入:1.数字的字符串形式 2.base,数字字符串的进制,比如:2进制、10进制。
// 3.bitSize的含义是⼤⼩限制,如果字符串转化的整形数据类型超过bitSize的最大值,那么输出的int64为bitSize的最大值,err就会显⽰数据超出范围。
i1, _ := strconv.ParseInt("1000", 10, 8)
println(i1)
i2, _ := strconv.ParseInt("1000", 10, 64)
println(i2)
f2, _ := strconv.ParseFloat("3.1415926", 64)
fmt.Println(f2, reflect.TypeOf(f2))
f1, _ := strconv.ParseFloat("3.1415926", 32)
fmt.Println(f1, reflect.TypeOf(f1))
// 返回字符串表示的bool值。它接受1、0、t、f、T、F、true、false、True、False、TRUE、FALSE;否则返回错误。
b1, _ := strconv.ParseBool("true")
fmt.Println(b1, reflect.TypeOf(b1))
b2, _ := strconv.ParseBool("T")
fmt.Println(b2, reflect.TypeOf(b2))
b3, _ := strconv.ParseBool("1")
fmt.Println(b3, reflect.TypeOf(b3))
b4, _ := strconv.ParseBool("100")
fmt.Println(b4, reflect.TypeOf(b4))
4.5、运算符
一个程序的最小单位是一条语句,一条语句最少包含一条指令,而指令就是对数据做运算,我们已经学完基本数据类型了,知道如何构建和使用一些最简单的数据,那么我们能对这些数据做什么运算呢,比如fmt.Println(1+1)
这条语句包含两个指令,首先是计算1+1的指令,1就是数据,+就是算术运算符中的相加,这样计算机就可以帮我们执行这个指令计算出结果,然后执行第二个指令,即将计算结果2打印在终端,最终完成这条语句。
4.5.1、算数运算符
运算符 | 描述 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 求余 |
如何判断一个整型数字是奇数还是偶数?
package main
import "fmt"
func main() {
// 加号
// 1.正数。 2.相加操作 3.字符串拼接
var n1 int = +10
fmt.Println(n1)
var n2 int = 4 + 7
fmt.Println(n2)
var n3 string = "你好" + "summer"
fmt.Println(n3)
fmt.Println(10 / 3) // 两个int类型数据运算,结果一定为整数类型
fmt.Println(10.0 / 3) // 浮点类型参与运算,结果为浮点类型。
// % 取模 等价公式 a%b=a-a/b*b
fmt.Println(10 % 3)
fmt.Println(-10 % 3)
fmt.Println(10 % -3)
fmt.Println(-10 % -3)
// ++ 自增操作:
var a int = 10
a++
fmt.Println(a)
// ++ 自增加1操作, --自减操作
// go语言里, ++ ,--操作非常简单,只能单独使用,不能参与到运算中去
// gp语言里,++ ,--只能在变量的后面,不能写在变量的前面, --a ++a 错误写法
}
4.5.2、关系运算符
运算符 | 描述 |
---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 |
< | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 |
<= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 |
4.5.3、逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。 |
|| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。 |
! | 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。 |
package main
import "fmt"
func main() {
// 与逻辑: && : 两个数值/表达式只要有一侧是false,结果一定为false
// 也叫短路与: 只要第一个数值/表达式的结果是false,那么后面的表达式等就不用运算了,直接结果是false
fmt.Println(true && true)
fmt.Println(true && false)
fmt.Println(false && true)
fmt.Println(false && false)
//或逻辑 ||: 两个数值、表达式只要有一侧是true, 结果一定是为true
// 也叫短路或: 只要第一个数值/表达式的结果是true,那么后面的表达式等就不用运算了,直接结果是true
fmt.Println(true || true)
fmt.Println(true || false)
fmt.Println(false || true)
fmt.Println(false || false)
//非逻辑 : 取相反的结果
fmt.Println(!true)
fmt.Println(!false)
/*
其他运算符:
& :返回变量的存储地址
* : 取指针变量对应的数值
*/
var age int = 18
fmt.Println("age对应的存储空间的地址为:", &age) //age对应的存储空间的地址为: 0xc000018088
var ptr *int = &age
fmt.Println(ptr)
fmt.Println("ptr这个指针指向的具体 数值为", *ptr) // ptr这个指针指向的具体 数值为 18
}
4.5.4、赋值运算符
运算符 | 描述 |
---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 |
+= | 相加后再赋值 |
-= | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 求余后再赋值 |
«= | 左移后赋值 |
»= | 右移后赋值 |
&= | 按位与后赋值 |
^= | 按位异或后赋值 |
|= | 按位或后赋值 |
++ | 自增 |
---|---|
– | 自减 |
4.5.5、运算符优先级
一句话: 为了提高优先级,可以加()
4.6、输入输出函数
4.6.1、输出函数
fmt.Print
有几个变种:
Print: 输出到控制台,不接受任何格式化操作 Println: 输出到控制台并换行 Printf : 只可以打印出格式化的字符串,只可以直接输出字符串类型的变量(不可以输出别的类型) Sprintf:格式化并返回一个字符串而不带任何输出
(1)Print 和Println
Print和Println()函数可以打印出字符串或变量的值。
name := "yuan"
age := 24
fmt.Print(name, age)
fmt.Println("hello world")
fmt.Println(name)
fmt.Println(age)
fmt.Println(name, age)
fmt.Println("姓名:", name, "年龄:", age)
(2)格式化输出(Printf)
Printf根据格式说明符号格式化并写入标准输出。Printf只打印字符串
比如上面打印一个人的基本细腻格式:
name := "yuan"
age := 24
isMarried := false
salary := 3000.549
fmt.Printf("姓名:%s 年龄:%d 婚否:%t 薪资:%.2f\n", name, age, isMarried, salary)
fmt.Printf("姓名:%v 年龄:%v 婚否:%v 薪资:%v\n", name, age, isMarried, salary)
fmt.Printf("姓名:%#v 年龄:%#v 婚否:%#v 薪资:%#v\n", name, age, isMarried, salary)
%v :以默认的方式打印变量的值 |
%#v :相应值的Go语法表示 |
%T :打印对应值的类型 |
%+d :带符号的整型,%d 不带符号的整型 |
%o :不带零的八进制,%#o 带零的八进制 |
%x :小写的十六进制,%X 大写的十六进制,%#x 带0x的十六进制 |
%b :打印整型的二进制 |
%t :打印true 或 false |
%s :输出字符串表示,%-5s 最小宽度为5(左对齐) |
%f 小数点而无指数,默认精度为6 |
%e 科学计数法,如-1234.456e+78 |
%p 带0x的指针,%#p 不带0x的指针 |
// 整形和浮点型
fmt.Printf("%b\n", 12) // 二进制表示:1100
fmt.Printf("%d\n", 12) // 十进制表示:12
fmt.Printf("%o\n", 12) // 八进制表示:14
fmt.Printf("%x\n", 12) // 十六进制表示:c
fmt.Printf("%X\n", 12) // 十六进制表示:c
fmt.Printf("%f\n", 3.1415) // 有小数点而无指数:3.141500
fmt.Printf("%.3f\n", 3.1415) // 3.142
fmt.Printf("%e\n", 1000.25) // 科学计数法: 1.000250e+03,默认精度为6
// 设置宽度
fmt.Printf("学号:%s 姓名:%-20s 平均成绩:%-4d\n", "1001", "alvin", 100)
fmt.Printf("学号:%s 姓名:%-20s 平均成绩:%-4d\n", "1002", "zuibangdeyuanlaoshi", 98)
fmt.Printf("学号:%s 姓名:%-20s 平均成绩:%-4d\n", "1003", "x", 78)
(3)Sprintf
Printf和Sprintf都是替换字符串,Printf是直接输出到终端,Sprintf是不直接输出到终端,而是返回该字符串
name := "yuan"
age := 24
isMarried := false
salary := 3000.549
info := fmt.Sprintf("姓名:%s 年龄:%d 婚否:%t 薪资:%.2f\n", name, age, isMarried, salary)
fmt.Println(info)
4.6.2、输入函数
go语言fmt包下有三个函数,可以在程序运行过程中从标准输入获取用户的输入:
(1)fmt.Scan
语法
func Scan(a ...interface{}) (n int, err error)
- Scan 从标准输入扫描文本,读取由空白符分隔的值保存到传递给本函数的参数中,换行符视为空白符。
- 本函数返回成功扫描的数据个数和遇到的任何错误。如果读取的数据个数比提供的参数少,会返回一个错误报告原因。
fmt.Scan从标准输入中扫描用户输入的数据,将以空白符分隔的数据分别存入指定的参数中。
(2)fmt.Scanf
语法
func Scanf(format string, a ...interface{})(n int, err error)
- Scanf从标准输入扫描文本,根据format参数指定的格式去读取由空白符分隔的值保存到传递给本函数的参数中。
- 本函数返回成功扫描的数据个数和遇到的任何错误。
package main
import "fmt"
func main() {
// 方式一: Sacnf
var age int
var name string
var score float32
var isVIP bool
fmt.Println("请输入学生的年龄,姓名,成绩,是否是VIP,使用空格进行分隔")
fmt.Scanf("%d %s %f %t", &age, &name, &score, &isVIP)
fmt.Printf("学生的年龄围殴:%v,姓名为:%v,成绩为:%v,是否为VIP:%v,", age, name, score, isVIP)
}
(3)fmt.Scanln
语法
func Scanln(a ...interface{}) (n int, err error)
- Scanln类似于Scan,它遇到换行立即停止扫描。
- 本函数返回成功扫描的数据个数和遇到的任何错误。
Scanln和Scan的区别就是Scanln遇到换行立即结束输入,而Scan则会将换行符作为一个空白符继续下一个输入
package main
import "fmt"
func main() {
// 实现功能,键盘录入学生的年龄,姓名,,成绩,是否是VIP
// 方式二 Scanln
var age int
fmt.Println("请录入学生的年龄:")
// 传入age的地址的目的:在Scanln函数中,对地址中的值进行改变的时候,实际外面的age被影响了
fmt.Scanln(&age) //录入数据的时候,类型一定要匹配,因为底层会自动判定类型的
var name string
fmt.Println("请录入学生的姓名:")
fmt.Scanln(&name)
var score float32
fmt.Println("请录入学生的成绩:")
fmt.Scanln(&score)
var isvip bool
fmt.Println("请录入学生是否为VIP:")
fmt.Scanln(&isvip)
// 将上述数据在控制台打印输出:
fmt.Printf("学生的年龄围殴:%v,姓名为:%v,成绩为:%v,是否为VIP:%v,", age, name, score, isvip)
}
4.7、常量与itoa
常量是一个简单的标识符,在程序运行时, 不会被修改的量,在Python、Java变成规范中,常量一般都是全大小字母,但是Golang中,大小写是具有特殊含义的,所以不一定所有常量都得大写
4.7.1 常量
常量是⼀个简单值的标识符,在程序运⾏时,不会被修改的量。 在Python、Java编程规范中,常量⼀般都是全⼤写字母,但是在Golang中,⼤⼩写是具有⼀定特殊含义的,所以不⼀定所有常量都得全⼤写。
声明赋值方式与变量接近,通过const
实现
const 常量名[数据类型] = value
数据类型可以忽略不写,Golang编译器会⾃动推断出数据类型。 在使⽤时,要注意以下⼏点:
- 数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型
- 满⾜多重赋值
- 常量只定义不使⽤,编译不会报错
- 常量可以作为枚举,常量组
- 常量组中如不指定类型和初始化值,则与上⼀⾏⾮空常量右值相同
- 显⽰指定类型的时候,必须确保常量左右值类型⼀致,需要时可做显⽰类型转换。
// (1)声明常量
const pai = 3.1415926
const e float64 = 2.7182818
fmt.Println(pai * pai)
// (2)常量也可以和变量一样一组一起声明
// const monday, tuesday, wednesday = 1, 2, 3
// 更推荐下面这种方式
const (
monday = 1
tuesday = 2
wednesday = 3
thursday = 4
friday = 5
saturday = 6
sunday = 7
)
const (
female = 0
male = 1
)
// ⼀组常量中,如果某个常量没有初始值,默认和上⼀⾏⼀致
const (
a int = 1
b
c = 2
d
)
fmt.Println(a, b, c, d)
4.7.2 iota计数器
iota
是go语言的常量计数器,只能在常量的表达式中使用。 使用iota
时只需要记住以下两点
1.
iota
在const
关键字出现时将被重置为0。2.
const
中每新增一行常量声明将使iota
计数一次(iota可理解为const
语句块中的行索引)。
const (
food = iota
cloth
bed
electric
)
fmt.Println(food, cloth, bed, electric)
const (
a = 1
b = iota
c = 6
d
e = iota
f
)
fmt.Println(a, b, c, d, e, f)
const (
b = 1 << (iota * 10)
kb
mb
gb
tb
pb
)
fmt.Println(b, kb, mb, gb, tb, pb)
标签:int,fmt,基础,语法,var,Printf,Println,main From: https://www.cnblogs.com/xiaohaoge/p/16839364.html