本文篇幅过长,仅供参考
B站韩顺平Go语言编程
Go语言标准库中文版
Golang sdk 下载
main()
函数定义的变量
或者import的包
如果没有使用到,代码不能编译通过Go语言保证了既能达到静态编译语言的安全和性能,又达到了动态语言开发和维护的高效率,使用一个表达式来形容Go语言:Go=C + Python
gc
,内存自动回收,不需要开发人员管理。CPS
并发模型(Communicating Sequential Processes)实现。channel
。vim /etc/profile
export GOROOT=/opt/go
export PATH=$GOROOT/bin:$PATH
export GOPATH=$HOME/goprojects/
SDK: 软件开发工具包,首先要配置好SDK
GOROOT: 指定SDK的安装目录
GOPATH: GO项目的目录
Path: 指定SDK目录下边的bin目录
单行注释:
//尽量用行注释来注释代码块
//Ctrl + / 快速注释
块注释:
/*
...
*/
// 块注释中不允许有块注释嵌套
为什么需要变量
变量是程序的基本组成单位,其相当于内存中的一个数据存储空间的表示,我们通过变量名可以访问到变量(值)
变量的基本使用:
1、声明变量(定义变量)
2、赋值
3、使用
gofmt -w xxx.go
可以自动对齐代码
package main
// import "fmt"
// import "unsafe"
import (
"fmt"
"unsafe"
)
func main() {
// 有符号整数(int)的范围
// int8 1bytes -128~127
// int16 2bytes -2^15~2^15-1
// int32 4bytes -2^31~2^31-1
// ...
var y int8 = 127 //当y为128时就会报错
fmt.Println("y=", y)
// 无符号整数(uint)的范围
// uint8 1bytes 0~255
// uint16 2bytes 0~2^15-1
// uint32 4bytes 0~2^32-1
// ...
var h uint8 = 255
fmt.Println("h=", h)
// rune 有符号整数类型 类似int32 表示一个Unicode码
// byte 无符号整数类型 与uint8等价 当要存储字符时选用byte
var a int = 9000
var b uint = 1
var c byte = 255
var d rune = 100
fmt.Println("a=", a, "b=", b, "c=", c, "d=", d)
// 查看某个变量的数据类型 fmt.Printf()
fmt.Printf("a 的类型 %T\n", a)
// 查看某个变量的字节大小
fmt.Printf("a 的类型 %T,占用的字节数是 %d", a, unsafe.Sizeof(a))
// 在Golang中使用变量的时候,遵守保小不保大的原则
// 即:在保证程序正确运行下,尽量使用占用空间小的数据类型,如年纪age可以使用byte类型
var age byte = 20
fmt.Println("age=",age)
// bit:计算机中的最小存储单位。byte:计算机中基本存储单元 1byte = 8bit
}
package main
import (
"fmt"
)
func main() {
var price float32 = 88.88
fmt.Println("price is ", price)
// go语言中小数类型分为两大类,单精度float32,双精度float64
// float32 4bytes
// float64 8bytes
// 浮点数=符号位+指数位+尾数位(浮点数都是有符号位的)
var num1 float32 = -0.00001
var num2 float64 = -78098238.08
fmt.Println("num1=",num1, "num2=", num2)
fmt.Println("num1=",num1, "num2=", num2)
// 尾数部分可能丢失,造成精度丢失,同样记录一个-123.00000901双精度要比单精度更精确
// Golang的浮点类型默认声明为float64
var num3 = 2.2
fmt.Printf("num3的数据类型为%T\n",num3)
// 十进制数形式:
num4 := 5.12
num5 := .123 // =>0.123
fmt.Println("num4=",num4, "num5=", num5)
fmt.Println("num4=",num4, "num5=", num5)
// 科学计数法形式
num6 :=5.12345e2 // 5.12345 * 10的2次方 512.345
num7 :=5.12345E2 // 5.12345 * 10的2次方 512.345
num8 :=5.12345E-2 // 5.12345 / 10的2次方 0.0512345
fmt.Println("num6=",num6, "num7=", num7, "num8", num8)
// 推荐使用float64
}
package main
import (
"fmt"
)
func main() {
var address string = "我爱你中国 12345 hello world"
fmt.Println(address)
// 字符串一旦赋值内容就不能修改:在go中字符串是不可变的
// var str = "hello"
// str[0] = 'a' 这样就会报错
// 字符串有两种表示形式
// (1)双引号,会识别转义字符
// (2)反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
str2 := "abc\nabc"
fmt.Println(str2)
str3 := `
afd
afdf
af
asf
afds
`
fmt.Println(str3)
// 字符串拼接 +
var str4 = "hello" + "world"
str4 += " haha!"
fmt.Println(str4)
// 当一个拼接的操作很长时,可以分行写,拼接符留在上一行
var str5 = "hello" + "world" +
"hello" +
"world"
fmt.Println(str5)
}
package main
import (
"fmt"
)
// 字符串就是一串固定长度的字符连接起来的字符序列
func main() {
// Golang中没有专门的字符类型,如果要存储单个(字母),一般使用byte来保存
// Golang的字符串是由字节组成的
var c1 byte = 'a'
var c2 byte = '0' // 字符的0
fmt.Println("c1=", c1, "c2=", c2) // c1= 97 c2= 48 会输出ASCII码值
fmt.Printf("c1=%c c2=%c\n", c1, c2) // c1=a c2=0
// var c3 byte = '京' // 结果会溢出 overflow
var c3 int = '京'
fmt.Printf("c3=%c c3对应的码值=%d\n", c3, c3) // c3=京 c3对应的码值=20140
// 如果我们保存的字符在ASCII表中,比如[0-9,a-z,A-Z]可以直接保存到byte
// 如果我们保存的字符对应码值大于255,这时我们可以考虑使用int类型保存
// 如果我们需要按照字符的方式输出,需要格式化输出,即 fmt.Printf("%c")
// utf-8编码包含了ASCII编码,英文字母1个字节,汉字3个字节
// 在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值
var c4 int = 22269 // 22269 -> '国'
fmt.Printf("c4=%c\n", c4)
// 由于字符类型本质是一个整数,所以其也是可以运算的,运算的时候是按照码值运算
var n1 = 10 + 'a'
fmt.Println("n1=", n1) //n1= 107
}
// 字符型存储到计算机中,需要将字符对应的码值(整数)找出来
// 存储:字符-->对应码值-->二进制-->存储
// 读取:二进制-->码值-->字符-->读取
// Go语言的编码都统一成了utf-8,所以不会有乱码出现
package main
import (
"fmt"
"unsafe"
)
func main() {
var b = false
fmt.Println("b=",b)
// bool类型占用的存储空间是1个字节
fmt.Println("b 的占用空间 =", unsafe.Sizeof(b))
// 布尔类型也叫bool类型,只允许其取值true or false
// 常用在循环语句中
// bool值默认是false
}
package main
import (
"fmt"
"strconv"
)
func main() {
var str string = "true"
var b bool
// 转bool
// strconv.ParseBool会返回两个值,第一个值是布尔值,第二个值是error值
// 我们只想获取到布尔值,对err不关心,所以可以用下划线 _ 来忽略掉err
b , _ = strconv.ParseBool(str)
fmt.Printf("b type %T b=%v\n",b, b)
// 输出结果:b type bool b=true
// 转int
var str2 string = "123456"
var n1 int64
var n2 int
n1, _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
fmt.Printf("n1 type %T n1=%v\n", n1, n1)
fmt.Printf("n2 type %T n2=%v\n", n2, n2)
var str3 string = "123.456"
var f1 float64
f1, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("f1 type %T f1=%v\n",f1 ,f1)
// 在String类型转成基本数据类型时,要确保String类型能够转成有效的数据
// 比如我们可以把"123"转成一个整数,但是不能把“hello”转为一个整数,如果这样Golang会将其转为0
// 如果n3没有转换成功,则会转成默认值0
var str4 string = "hello"
var n4 int64 = 11
n4, _ = strconv.ParseInt(str4, 10, 64)
fmt.Printf("n4 type %T n4=%v\n", n4, n4)
// 输出结果:n4 type int64 n4=0
// 字符串转换为bool的情况会转为默认false
var str5 string = "hellook"
var b2 bool = true
b2 , _ = strconv.ParseBool(str5)
fmt.Printf("b2 type %T b2=%v\n",b2, b2)
// 输出信息:b2 type bool b2=false
}
// 在开发中,经常需要将基本数据类型转成string类型
// 或者将string类型转成基本数据类型
package main
import (
"fmt"
_ "unsafe"
"strconv"
)
func main() {
var num1 int = 99
var num2 float64 = 22.222
var b bool = true
var mychar byte = 'h'
var str string //空的str
// 使用第一种方式来转换 fmt.Sprintf方法
str = fmt.Sprintf("%d", num1)
fmt.Printf("str type %T str=%q\n", str, str)
str = fmt.Sprintf("%f", num2)
fmt.Printf("str type %T str=%q\n", str, str)
str = fmt.Sprintf("%t", b)
fmt.Printf("str type %T str=%q\n", str, str)
str = fmt.Sprintf("%c", mychar)
fmt.Printf("str type %T str=%q\n", str, str)
// 第二种方式转换 strconv 函数
var num3 int = 99
var num4 float64 = 23.456
var b2 bool = true
str = strconv.FormatInt(int64(num3), 10)
fmt.Printf("str type %T str=%q\n", str, str)
// 'f'格式;10表示小数部分保留几位;64表示这个小数是float64
str = strconv.FormatFloat(num4, 'f', 10, 64)
fmt.Printf("str type %T str=%q\n", str, str)
// 输出:str type string str="23.4560000000"
str = strconv.FormatBool(b2)
fmt.Printf("str type %T str=%q\n", str, str)
// 第三种 strconv包中有一个函数Itoa,可以直接把一个int转为string
var num5 int = 4567
str = strconv.Itoa(num5)
fmt.Printf("str type %T str=%q\n", str, str)
}
package main
import (
"fmt"
_ "unsafe" // 如果我们没有使用到一个包,但是不想去掉,就在前边加一个 _ 表示忽略
)
func main() {
var i int = 100
// 将i ==> float
var n1 float32 = float32(i)
var n2 int8 = int8(i)
var n3 int64 = int64(i)
fmt.Printf("i=%v n1=%v n2=%v n3=%v\n", i, n1, n2, n3)
// Go中数据类型的转换可以是从表示范围小-->表示范围大 也可以范围大-->范围小
// 被转换的是变量存储的数据(即值),变量本身的数据类型并没有发生变化
// 在转换中,比如讲int64 转换成 int8 [-128~127] ,编译时不会报错
// 只是转换的结果是按照溢出处理的,和我们希望的结果不一样
var num1 int64 = 999999
var num2 int8 = int8(num1)
fmt.Println("num2=", num2)
// 输出结果:num2= 63
var (
m1 int32 = 12
m2 int64
m3 int8
)
m2 = int64(m1) + 20
m3 = int8(m1) + 20
fmt.Println("m2=", m2, "m3=", m3)
var (
b1 int32 = 12
b2 int8
// b3 int8
)
b2 = int8(b1) + 127 // 编译通过,但是结果不是127+12,按照溢出处理,输出结果为·117
// b3 = int8(b1) + 128 编译不通过
fmt.Println(b2)
}
package main
import (
"fmt"
)
// 可以从控制台接收用户信息(姓名、年龄、薪水、是否通过测试)
func main() {
var name string
var age byte
var sal float32
var isPass bool
// scanf可以按照指定的格式输入
fmt.Println("姓名、年龄、薪水、是否通过测试,输入时请使用空格隔开")
fmt.Scanf("%s %d %f %t", &name, &age, &sal, &isPass)
fmt.Printf(" 名字是%v \n 年龄是 %v \n 薪水是%v \n 是否通过考试 %v \n", name, age, sal, isPass)
}
package main
import (
"fmt"
)
// 可以从控制台接收用户信息(姓名、年龄、薪水、是否通过测试)
func main() {
// 先声明变量
var name string
var age byte
var sal float32
var isPass bool
fmt.Println("请输入姓名:")
fmt.Scanln(&name)
fmt.Println("请输入年龄:")
fmt.Scanln(&age)
fmt.Println("请输入薪水:")
fmt.Scanln(&sal)
fmt.Println("请输入是否通过考试:")
fmt.Scanln(&isPass)
fmt.Printf(" 名字是%v \n 年龄是 %v \n 薪水是%v \n 是否通过考试 %v \n", name, age, sal, isPass)
}
名称 | 含义 |
---|---|
\t | 一个制表位,实现对齐的功能 |
\n | 换行符 |
\ | 一个 \ |
" | 一个 " |
\r | 一个回车,从当前行的最前端开始输出,覆盖之前的内容 |
// 例子
package main
import "fmt"
func main() {
fmt.Println("tom\tJerry")
fmt.Println("tom\nJerry")
fmt.Println("D:\\goproject\\src\\go_code\\project01\\main")
fmt.Println("你好我是RSQ\r哈哈")
}
package main
import (
"fmt"
)
func main() {
// / %
// 运算的数都是整数,那么除后,去掉小数部分,保留整数部分
fmt.Println(10 / 3) // 输出3
var a1 float32 = 10 / 4
fmt.Println(a1) // 输出2
// 最后所取数取决于参与运算的数值类型
// 若希望保留小数部分,则需要有浮点数参与运算
var a2 float32 = 10.0 / 4
fmt.Println(a2) // 输出2.5
// 取模运算%
// 有个公式 a % b = a - a / b * b
fmt.Println("10%3=", 10 % 3) // = -1
fmt.Println("-10%3=", -10 % 3) // = -10 - (-10) / 3 * 3 = -10 - (-9) = -1
fmt.Println("10%-3=", 10 % -3) // = 1
fmt.Println("-10%-3=", -10 % -3) // = (-10) - (-10) / (-3) * (-3) = -10 - (-9) = -1
// ++ -- 的使用
var i int = 10
i++
fmt.Println("i=", i)
i--
fmt.Println("i=", i)
// 关系运算符,其结果都是bool型,也就是要么是true,要么是false
// 关系表达式经常用在if结构的条件中,或循环结构的条件中
// == != < > <= >=
// 比较运算符==不能写成一个 = 号,一个代表赋值
var n1 int = 9
var n2 int = 8
fmt.Println(n1 == n2) // false
fmt.Println(n1 != n2) // true
fmt.Println(n1 > n2) // true
fmt.Println(n1 < n2) // false
fmt.Println(n1 >= n2) // true
fmt.Println(n1 <= n2) // false
flag := n1 > n2
fmt.Println("flag=", flag) // true
// 逻辑运算符
// 用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个bool值。
var age int = 40
if age > 30 && age < 50 {
fmt.Println("ok1")
}
if age > 30 || age < 40 {
fmt.Println("ok2")
}
if age < 40 {
fmt.Println("ok3")
} else if age >= 40 {
fmt.Println("ok4")
}
if !(age > 30) {
fmt.Println("ok5")
}
var m int = 10
// 调用一下test函数,短路与
if m > 9 && test() {
fmt.Println("okoko")
}
// 交换两个变量的值
// 法一:
m1 := 10
m2 := 5
t := m1
m1 = m2
m2 = t
fmt.Println("m1和m2交换后值为:", m1, m2)
// 法二,可以不使用中间变量:
m1, m2 = m2, m1
fmt.Println("m1和m2交换后值为:", m1, m2)
// 法三:但是这种会有溢出的风险
// a = a + b
// b = a - b
// a = a - b
// 赋值运算符的左边 只能是变量,右边可以是变量、表达式、常量值
// 表达式:任何有值的都可以看做表达式
var d int
d = m1
d = 8 + 2 * 8
d = test1() + 90
d = 890
fmt.Println(d)
}
func test1() int{
return 90
}
func test() bool {
fmt.Println("test......")
return true
}
package main
import (
"fmt"
)
// & * 运算符
func main() {
a := 100
fmt.Println("a 的地址=", &a)
var ptr *int = &a
fmt.Println("Ptr 指向的值是=", *ptr)
// 求三个数中的最大值
var b int = 10
var c int = 50
var d int = 30
var max int
if b > c && b > d {
max = b
} else if c > b && c > d {
max = c
} else {
max = d
}
fmt.Println("最大值max=", max)
}
// go语言中没有三元运算符,如果要实现可以用if else来实现
// 传统三元 a = b > c ? b : c
对于有符号的数而言:
1)二进制最高位是符号位,0表示正数,1代表负数
1 ====》「0000 0001」 -1 ====》「1000 0001」
2)正数的原码、反码和补码都一样
3)负数的反码=它的原码,符号位不变,其他位取反(0->1,1->0)
1 ====》反码:「0000 0001」 补码:「0000 0001」
-1 ====》反码:「1000 0001」 补码:「1111 1111」
4)负数的补码等于它的反码+1
5)0的反码和补码都是0
6)在计算机运算的时候,都是以补码的方式来运算的
Golang中有三个位运算
1)&:与运算:两位全为1,结果为1,否则为0
2)|:或运算:两位有一个为1,结果为1,否则为0
3)^:异或运算:两个一个为0,一个为1,结果为1,否则为0
2&3 0000 0010 &
0000 0011 ==》0000 0010 =》 2
2|3 0000 0011 = 》3
2^3 0000 0001 = 》1
Golang移位运算
>>右移位运算符:低位溢出,符号位不变,并用符号位补溢出的高位
<<左移位运算符:符号位不变,低位补0
1>>2 0000 0001 ==> 0000 0000 ===>0
1<<2 0000 0001 ==> 0000 0100 ===>4
示例:
package main
import (
"fmt"
)
func main() {
var a int = 1 >> 2
var b int = -1 >> 2
var c int = 1 << 2
var d int = -1 << 2
fmt.Println("a=", a) // a= 0
fmt.Println("b=", b) // b= -1
fmt.Println("c=", c) // c= 4
fmt.Println("d=", d) // d= -4
fmt.Println(2&3) // 2
fmt.Println(2|3) // 3
fmt.Println(-2^2) // -4
fmt.Println(2^3) // 1
fmt.Println(13&7) // 5
fmt.Println(5|4) // 5
fmt.Println(-3^3) // -2
}
package main
import (
"fmt"
)
func main() {
// (1)假如还有97天放假,问还有xx个星期零xx天
days := 97
week := days / 7
leftdays := days % 7
fmt.Printf("还有%d个星期零%d天 \n", week, leftdays)
// (2)定义一个变量保存华氏温度,华氏温度转换摄氏温度的公式如下:
// 5/9*(华氏温度-100),请求出华氏温度对应的摄氏温度
var huashi float32 = 134.2
// 下边的5一定要写成5.0,不然5/9=0
var sheshi float32 = 5.0 / 9 * (huashi - 100)
fmt.Printf("%v 对应的摄氏温度为 %v", huashi, sheshi)
}
操作符使用注意事项:
(1)Golang的自增自减只能当做一个独立的语言使用,不能这样使用: b := a++ 或者 b := a--
(2)Golang的++和--只能写在变量的后边,不能卸载变量的前面,即:只有a++ a--而没有 ++a --a
(3)Golang的设计者去掉c/java中的自增自减的容易混淆的写法,让Golang更加简洁,统一(强制性的)
逻辑运算符一览:
假定A为True,B为False
&& 逻辑与运算符。如果两边都是True则其才为True,否则为False。 (A && B)为False
|| 逻辑或运算符。如果两边有一个为True,则其位True,否则为False (A || B)为True
! 逻辑非运算符。如果条件为True,则逻辑为False,否则为True (A && B)为True
&&也叫短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false
||也叫短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true
赋值运算符:
=、+=、-=、*=、/=、%=
位赋值运算符(跟二进制相关)
<<== 左移后赋值 C <<== 2 等于 C = C << 2
>>== 右移后赋值
&= 按位与后赋值
^= 按位异或后赋值
|= 按位或后赋值
运算符优先级:
1、括号,++,--
2、单目运算符 + - ! ~
3、算术运算符
4、移位运算符
5、关系运算符
6、位运算符
7、逻辑运算符
8、赋值运算符
9、逗号
只有单目运算符、赋值运算符是从右向左运算的
转换原理:
八进制转10进制:从最低位开始(右边的),将每个位上的数提取出来,乘以8的(为数-1)次方,然后求和。
0123 = 3 * 1 + 2 * 8 + 1 * 8 * 8 = 3 + 16 + 64 = 83
16进制转换10进制:从最低位开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
0x34A = 10 * 1 + 4 * 16 + 3 * 16 * 16 = 10 + 64 + 768 = 842 (A=10,B=11,C=12,D=13,E=14,F=15)
110001100 = 2^2 + 2^3 + 2^7 + 2^8 = 4 + 8 + 128 + 256 = 396
02456 = 6 * 1 + 5 * 8 + 4 * 8 * 8 + 2 * 8 * 8 * 8 = 1326
0xA45 = 5 * 1 + 4 * 16 + 10 * 16 * 16 = 2629
进制规则:将该数不断除以2/8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的2/8进制数
二进制转八进制:将二进制数每三位一组(从低位开始组合),转成对应的八进制数即可。
11010101 = 11 010 101 = 03 2 5 = 0325
二进制转16进制:将二进制数四位一组(从低位开始组合),转成对应的十六进制数即可。
11010101 = 1101 0101 = 0x D 5 = 0xD5
八进制转二进制:跟上述反之即可,将八进制每1位,转成对应的一个3位的二进制数即可
16进制转二进制:将16进制每1位,转成对应的一个4位的二进制数即可。
例子:
package main
import (
"fmt"
)
func main() {
var i int = 5
// 打印二进制%b
fmt.Printf("%b\n", i)
// 八进制
var j int = 011
fmt.Println("j=", j) // 打印出9
// 十六进制
var k int = 0x11
fmt.Println("k=", k)
}
package main
import (
"fmt"
)
func main() {
var i int = 100
fmt.Printf("i的内存空间地址=%v\n", &i)
// ptr是一个指针变量
// ptr指针指向的值 *int
// ptr本身的地址 &ptr
var ptr *int = &i
fmt.Println("ptr指针变量的值=",ptr)
fmt.Printf("ptr指针变量内存地址=%v\n", &ptr)
fmt.Printf("ptr指针变量指向的地址的值=%v\n", *ptr)
// 讲num的值赋值给ptr,并通过ptr去修改num的值
var num int = 9
fmt.Printf("num address %v\n", &num)
var ptr1 *int
ptr1 = &num
*ptr1 = 10
fmt.Println("num=",num )
// 练习:以下代码输出什么内容
var a int = 300
var b int = 400
var ptr2 *int = &a
*ptr2 = 100
ptr2 = &b
*ptr2 = 200
fmt.Printf("a=%d,b=%d,*ptr2=%d",a ,b ,*ptr2)
// 输出内容:a=100,b=200,*ptr2=200
}
(1)基本数据类型,变量存储的就是值,也叫值类型
(2)获取变量的地址,用&,比如:var num int 获取num的地址:&num
(3)指针类型,变量存的是一个地址,这个地址指向的空间存的才是值,比如:var ptr *int = &num
(4)获取指针类型所指向的值,使用:*,比如:var ptr *int,使用*ptr获取ptr指向的值
(5)值类型,都有对应的指针类型,形式为 *数据类型,比如int的对应指针就是 *int,
float32对应的指针类型就是 *float32。以此类推
(6)值类型包括:基本数据类型 int系列,float系列,bool,string、数组和结构体struct
值类型变量直接存储时,内存通常在栈中分配(golang中有逃逸分析,所以有可能值类型还会在堆中)
GoLang编辑器会根据变量使用多长时间来决定在哪,比如一个变量生存时间比较长,那可能就放在堆区
还比如有一个值类型在其他函数中可能也会用到,那么这个值类型就有可能会在堆区存放
(7)引用类型:指针、slice切片、map、管道chan、interface等都是引用类型
引用类型变量存储的是一个内存地址,这个地址对应的空间才是真正存储数据(值),
内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,有GC来回收。
if的条件语句不能是赋值语句
package main
import (
"fmt"
)
func main() {
// declare variable
var age byte
fmt.Println("请输入年龄:")
fmt.Scanln(&age)
// 变量作用域只在本分支循环内
if age > 18 {
fmt.Println("应该付法律责任了")
} else {
fmt.Println("You will die.")
}
if age := 20; age > 18 {
fmt.Println("应该付法律责任了")
}
// 嵌套分支不宜过多,最多控制在三层
var month byte
fmt.Println("请输入月份:")
fmt.Scanln(&month)
fmt.Println("请输入年龄:")
fmt.Scanln(&age)
if month >= 4 && month <= 10 {
// 旺季
if age >= 18 && age < 60 {
fmt.Printf("%v 月旺季,%v 岁成人票价是60", month, age)
} else if age < 18 {
fmt.Printf("%v 月旺季,%v 岁儿童半价", month, age)
} else {
fmt.Printf("%v 月旺季,%v 岁老人票价1/3", month, age)
}
} else if month >= 1 && month < 4 || month > 10 && month <= 12 {
// 淡季
fmt.Println("淡季成人票价:40")
fmt.Println("淡季儿童票价:20")
} else {
fmt.Println("错误的输入信息,请重新输入")
}
}
示例:
package main
import (
"fmt"
"math"
)
func main() {
// 1、声明两个int32变量并赋值,判断两者之和是否大于50,是的话输出hello,world
var a1 int32 = 31
var b11 int32 = 30
sum1 := a1 + b11
if sum1 > 50 {
fmt.Println("hello,world")
}
// 2、声明2个float32型变量并赋值,判断第一个数是否大于10,第二个数是否小于20,打印两者之和
var a11 float32 = 11.0
var a22 float32 = 12.0
if a11 > 10 && a22 < 20{
fmt.Println("sum=", (a11 + a22))
}
// 3、定义两个int32变量,判断二者之和能否被3又被5整除,并打印提示信息
var b1 int32 = 5
var b2 int32 = 11
sum3 := b1 + b2
// t1 = sum3 / 3
// t2 = sum3 / 5
if sum3 % 3 == 0 && sum3 % 5 == 0 {
fmt.Println("符合要求")
} else {
fmt.Println("不符合要求")
}
// 4、判断一个年份是否是闰年,闰年的条件是符合下面两者之一:
// (1)年份能被4整除,但是不能被100整除
// (2)能被400整除
var year int32 = 2000
if year %4 == 0 && year % 100 != 0 {
fmt.Printf("%d是闰年\n", year)
} else if year % 400 == 0 {
fmt.Printf("%d是闰年\n", year)
} else {
fmt.Printf("%d不是闰年\n", year)
}
// 求ax^2 + bx + c = 0 方程的根;如果b^2- 4ac > 0 则有两个解;b^2- 4ac = 0,则有一个解;b^2- 4ac < 0 无解
// 引入一个包math,里边有很多函数,比喻可以求平均值、绝对值等等
var a float64 = 2.0
var b float64= 4.0
var c float64 = 2.0
m := b * b - 4 * a * c
if m > 0 {
x1 := (-b + math.Sqrt(m)) / (2 * a)
x2 := (-b - math.Sqrt(m)) / (2 * a)
fmt.Printf("x1=%v x2=%v", x1, x2)
} else if m == 0 {
x1 := (-b - math.Sqrt(m)) / (2 * a)
fmt.Printf("x1=%v", x1)
} else {
fmt.Printf("无解")
}
}
package main
import (
"fmt"
)
func main() {
// 1、打印1~100之间所有是9的倍数的整数的个数及总和
var max int = 100
var count int = 0
var sum int = 0
for i := 1; i <= max; i++ {
if i % 9 == 0 {
count++
sum += i
}
}
fmt.Printf("count=%v sum=%v\n", count, sum)
// 2、打印以下内容
// 0 + 6 = 6
// 1 + 5 = 6
// 2 + 4 = 6
// 3 + 3 = 6
// 4 + 2 = 6
// 5 + 1 = 6
// 6 + 0 = 6
// 法一:
for i := 0; i <= 6; i++ {
for j :=6; j >= 0; j-- {
if i + j == 6 {
fmt.Printf("%d + %d = %d\n", i, j, (i + j))
}
}
}
fmt.Printf("\n")
// 法二:
var n int = 60
for i := 0; i <= n; i++ {
fmt.Printf("%v + %v = %v \n", i, n - i, n)
}
}
package main
import (
"fmt"
)
// 统计3个班成绩情况,每个班有5名同学
// 1、求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]
// 2、求出一共有多少人及格
func main() {
var classNum int = 3
var stuNum int = 5
var passCount int = 0
var ave float64 = 0.0
// var ave float64 = 0.0
for j := 1; j <=classNum; j++ {
var sum float64 = 0.0
for i := 1; i <= stuNum; i++ {
var score float64
fmt.Printf("请输入第%d班的%d个学生的成绩\n", j, i)
fmt.Scanln(&score)
// 累计总分
sum += score
// 判断分数是否及格
if score >= 60 {
passCount++
}
}
fmt.Printf("第%d个班级的平均分是%v\n", j, sum / float64(stuNum))
// 将各个班的总成绩累积到ave变量
ave += sum
}
fmt.Printf("所有班级的总成绩是%v 所有班级的平均分%v\n", ave, ave / (float64(stuNum * classNum)))
fmt.Printf("及格人数有%v名学生\n", passCount)
}
package main
import (
"fmt"
)
func main() {
// 打印半个金字塔
/*
*
**
***
****
*****
******
*/
for i :=1; i <= 6; i++ {
for j := 1; j <= i; j++ {
fmt.Print("*")
}
fmt.Println()
}
// 打印整个金字塔
// 思路:每行*的数量有个规律 即 2 * 层数 - 1
// 每一行前的空格数量等于总的层数-当前层数
/*
*
***
*****
*******
*********
***********
*/
var floor int = 7
// i表示层数
for i :=1; i <= floor; i++ {
// k表示在每一行前打印多少空格
for k := 1; k <=floor - i; k++ {
fmt.Print(" ")
}
// j表示每一行打印多少*
for j := 1; j <= 2 * i - 1; j++ {
fmt.Print("*")
}
fmt.Println()
}
fmt.Println()
// 打印空心金字塔
/*
*
* *
* *
* *
*********
*/
var floor1 int = 7
// i表示层数
for i :=1; i <= floor1; i++ {
// k表示在每一行前打印多少空格
for k := 1; k <=floor1 - i; k++ {
fmt.Print(" ")
}
// j表示每一行打印多少*
for j := 1; j <= 2 * i - 1; j++ {
if j == 1 || j == 2 * i - 1 || i == floor1{
fmt.Print("*")
} else {
fmt.Print(" ")
}
}
fmt.Println()
}
fmt.Println()
// 打印实心菱形
var n int = 7
// 打印上半部分
for i := 1; i <= n; i++ {
for k := 1; k <= n-i; k++ {
fmt.Print(" ")
}
for j := 1; j <= 2 * i-1; j++ {
fmt.Print("*")
}
fmt.Println()
}
// 打印下半部分
for i := n - 1; i >= 1; i-- {
for k := 1; k <= n-i; k++ {
fmt.Print(" ")
}
for j := 1; j <= 2 * i-1; j++ {
fmt.Print("*")
}
fmt.Println()
}
// 打印空心菱形
// 打印上半部分
var n1 int = 7
for i :=1; i <= n1; i++ {
// k表示在每一行前打印多少空格
for k := 1; k <=n1 - i; k++ {
fmt.Print(" ")
}
// j表示每一行打印多少*
for j := 1; j <= 2 * i - 1; j++ {
if j == 1 || j == 2 * i - 1 {
fmt.Print("*")
} else {
fmt.Print(" ")
}
}
fmt.Println()
}
// 打印下半部分
for i :=n1 - 1; i >= 1; i-- {
// k表示在每一行前打印多少空格
for k := 1; k <=n1 - i; k++ {
fmt.Print(" ")
}
// j表示每一行打印多少*
for j := 1; j <= 2 * i - 1; j++ {
if j == 1 || j == 2 * i - 1 {
fmt.Print("*")
} else {
fmt.Print(" ")
}
}
fmt.Println()
}
}
package main
import (
"fmt"
)
func main() {
// 打印 9 * 9 乘法口诀
for i := 1; i < 10; i++ {
for j :=1; j <= i; j++ {
fmt.Printf("%v * %v = %v\t", j, i, (i * j))
}
fmt.Println()
}
}
package main
import (
"fmt"
)
func main() {
// 判断一个数是不是水仙花数
// 水仙花数是指一个三位数,其各个位上数字立方和等于其本身。
// 如:153 = 1*1*1 + 3*3*3 + 5*5*5
for i := 100; i <= 999; i++ {
var j = i / 100
var k = i /10 % 10
var l = i % 10
if i == j * j * j + k * k * k + l * l * l {
fmt.Println(i)
}
}
}
package main
import (
"fmt"
)
// 根据输入的月份和年份,求出该月的天数(1-12月)
// 1、3、5、7、8、10、12 ==> 31天
// 2 ==> 闰年29天,平年28天
// 其它 ==> 30天
func main() {
var year int
var month int
fmt.Println("请输入一个月份")
fmt.Scanln(&month)
fmt.Println("请输入一个年份")
fmt.Scanln(&year)
switch {
case month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12:
run(year)
fmt.Printf("%v月31天\n", month)
case month == 2:
if run(year) == 1 {
fmt.Printf("%v月是29天", month)
} else if run(year) == 2 {
fmt.Printf("%v月是28天", month)
}
case month == 4 || month == 6 || month == 9 || month == 11:
run(year)
fmt.Printf("%v月30天\n", month)
default:
fmt.Println("输入错误")
}
}
func run(b int) int {
if b % 4 == 0 && b % 100 != 0 || b % 400 == 0 {
fmt.Printf("%v年是润年", b)
return 1
} else {
fmt.Printf("%v年是平年", b)
return 2
}
}
package main
import (
"fmt"
)
func main() {
// for循环,打印10句Hello,World
// for i := 0; i <= 10; i++ {
// fmt.Println("Hello,World")
// }
// for循环第二种用法
k := 1
for k <= 10 {
fmt.Println("Hello,World")
k++
}
// for循环第三种用法
// 等价于for ; ; {} 是一个无限循环,通常需要配合break语句来使用
j := 1
for {
if j <= 10 {
fmt.Println("Hello,World")
j++
} else {
break
}
}
// for-range方式来遍历字符串和数组
// 法一:传统方式
var str string = "hello,world"
for i := 0; i < len(str); i++ {
fmt.Printf("%c\n", str[i])
}
// 法二:for-range
// 用这种方法不会出现乱码,因为其是按照字符来遍历的
for index, val := range str {
fmt.Printf("index=%d value=%c \n", index, val)
}
// 如果字符串含有中文,那么传统的遍历字符串的方式就是错误的,会出现显示乱码
// 原因是因为传统对字符串的遍历是按照字节来遍历的,而一个汉字在UTF-8编码是对应三个字节,所以会报错
// 解决办法:需要将str转成[]rune切片
var str1 string = "hello,world北京"
str2 := []rune(str1) //就是把str转成[]rune切片
for i := 0; i < len(str2); i++ {
fmt.Printf("%c\n", str2[i])
}
}
// Golang中没有while和do...while的语法
// 可以通过for循环来实现
for {
if 表达式 {
//循环语句
}
}
// do while用for实现
// 循环变量初始化
for {
循环操作语句
循环变量迭代
if 循环条件表达式 {
break //跳出循环
}
}
var j int = 1
for {
fmt.Println("hellmno",j)
j++
if j > 10 {
break
}
}
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 100; i++ {
if i % 2 == 0 {
continue
}
fmt.Println("i=", i)
}
var positiveCount int
var negativeCount int
var num int
for {
fmt.Println("请输入一个整数:")
fmt.Scanln(&num)
if num == 0 {
break
} else if num > 0 {
positiveCount++
continue
}
negativeCount++
}
fmt.Printf("正数的个数是:%v \n负数的个数是:%v", positiveCount, negativeCount)
}
package main
import (
"fmt"
)
func main() {
// 某人有100000元
// 当现金>50000,每次交5%
// 当现金<=50000,每次交1000
// 计算该人可以经过多少次路口
var crash float64 = 100000
var count int = 0
// var sum int
for {
if crash > 50000 {
crash = crash - crash * 0.05
count++
continue
} else if crash > 0 && crash <= 50000 {
crash = (crash - 1000)
count++
} else if crash < 0 {
break
}
}
fmt.Printf("该人一共可以经过%v次路口", count)
}
package main
import (
"fmt"
)
func main() {
for i := 0; i < 4; i++ {
for j := 0; j < 10; j++{
if j == 2 {
continue
}
fmt.Println("j=",j)
}
}
}
continue语句是结束本次循环,如果循环中的后续还有代码将不会再执行,直接执行下一次循环。
continue语句出现在多层嵌套的循环语句中,可以通过标签指明要跳过的是哪一层循环,这个和前面的break标签的使用规则是一样的
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
// 生成一个随机数,还需要设置rand种子
// time.Now().Unix():返回一个从1970:01:01的0时0分0秒到现在的秒数
rand.Seed(time.Now().Unix())
// 随机生成1-100的整数(由于上边的rand一直在变化,所以下边也会一直变化)
n := rand.Intn(100) + 1 // 默认[0 100) 不包括100,所以需要 + 1
fmt.Println(n)
// 随机生成一个数,看生成这个数一共用了几次
var count int = 0
for {
n := rand.Intn(100) + 1
fmt.Println(n)
count++
if (n == 99) {
break
}
}
fmt.Printf("生成99一共运行了%v次", count)
}
package main
import (
"fmt"
)
func main() {
// 求100以内的和
var sum int = 0
for i := 0; i <= 100; i++ {
sum += i
if sum > 20 {
fmt.Println("第一次大于20时,数值是", i)
break
}
}
// 用户有三次登录机会
var name string
var Pass string
var loginChance int = 3
for i := 1; i <= 3; i++{
fmt.Println("请输入账号:")
fmt.Scanln(&name)
fmt.Println("请输入密码:")
fmt.Scanln(&Pass)
if name == "张无忌" && Pass == "888" {
fmt.Println("登陆成功")
break
} else {
loginChance--
if loginChance != 0 {
fmt.Printf("登录错误,你还有%v次机会", loginChance)
} else {
break
}
}
}
if loginChance == 0 {
fmt.Println("机会用完")
}
}
// break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的哪一层语句块
// 标签基本使用
label1:
for {
label2:
for {
if {
break label1
break label2
}
}
}
return使用在方法或者函数中,表示跳出所在的方法或函数。
一般return是用在函数中
package main
import (
"fmt"
)
func main() {
// 演示goto语句
// goto语句一般会和if语句一块使用
var n int = 20
fmt.Println("ok1")
if n > 20 {
goto label1
}
fmt.Println("ok2")
fmt.Println("ok3")
fmt.Println("ok4")
label1:
fmt.Println("ok5")
fmt.Println("ok6")
// 输出信息
// ok1
// ok5
// ok6
}
// 1)go语言的goto语句可以无条件地转移到制定程序中的指定的行
// 2)goto语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能
// 3)在Go程序设计中,一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序产生困难。
基本语法:
goto label
label: statement