目录
一、变量
在go中声明变量有多种语法。
1.1声明变量
var名称类型是声明单个变量的语法。
以字母或下划线开头,由一个或多个字母、数字、下划线组成
声明一个变量
第一种, 指定变量类型,声明后若不赋值,使用默认值
var name type
name = value
第二种,根据值自行判定变量类型(类型推断Type inference)
如果一个变量有一个初始值,Go将自动能够使用初始值来推断该变量的类型,因此,如果变量具有初始值,则可以省略变量声明中的类型。
var name=value
第三种,省略var, 注意 := 左侧的变量不应该是已经声明过的(多个变量同时声明时,至少保证一个是新变量), 否则会导致编译错误(简短声明)
这种方式只能被用在函数体内,而不可以用二全局变量的声明与赋值。
多变量声明
第一种, 以逗号分隔,声明与赋值分开, 若不赋值,存在默认值
var name1, name2, name3 type
name1, name2, name3 = v1, v2, v3
第二种, 直接赋值,下面的变量类型可以是不同的类型
var name1, name2, name3=v1,v2,v3
第三种, 集合类型
var (
name1 type1
name2 type2
)
package main
import "fmt"
func main() {
/*
变量: variable
概念:一小块内存,用于存储数据,在程序运行过程中数值可以改变
使用:
step1: 变量的声明,也叫定义
第一种: var 变量名 = 数据类型
变量名 = 赋值
第二种: 类型推断, 省略数据类型
var 变量名 = 赋值
第三种: 简短声明, 省略var
变量名 := 赋值
step2: 变量的访问,赋值和取值
直接根据变量名访问
使用指针地址访问
go特性:
静态语言: 强类型语言 go java c++ c#
动态语言: 弱类型语言 javascipt php python ruby
*/
//第一种:定义变量,然后进行赋值
var num1 int
num1 = 30
fmt.Printf("num1的数值是%d\n", num1)
var num2 int = 15
fmt.Printf("num2的数值是 %d\n", num2)
//第二种:类型推断
var name = "Jack"
fmt.Printf("类型是: %T, 数值是%s\n", name, name)
//第三种:简短定义,也叫简短声明
sum := 200
fmt.Println(sum)
//多个变量同时定义
var a, b, c int
a = 1
b = 2
c = 3
fmt.Println(a, b, c)
var m, n int = 100, 300
fmt.Println(m, n)
var n1, f1, s1 = 100, 3.14, "longlongago"
fmt.Println(n1, f1, s1)
var (
studentName = "李小明"
age = 18
sex = "男"
)
fmt.Printf("学生姓名: %s; 年龄: %d;性别: %s\n", studentName, age, sex)
}
使用&变量名,访问内存地址:
var num int
num = 100
fmt.Printf("num的数值是: %d, 地址是: %p\n", num, &num)
num = 200
fmt.Printf("num的数值是: %d, 地址是: %p\n", num, &num)
注意事项:
变量必须先定义才能使用。
go语言是静态语言,要求变量的类型和赋值的类型必须一致。
变量名不能冲突,(同一个作用域内不能冲突)
简短定义方式,左边的变量名至少有一个是新的。
简短定义方式,不能定义全局变量。
变量的零值,也叫默认值
变量定义了就要使用,否则无法通过编译。
二、常量
1.常量声明
常量是一个简单的标识符,在程序运行时,不会被修改的量。
const identifiter [type] = value
显式类型定义: const b string="abc"
隐式类型定义: const b = "abc"
func main() {
/*
常量:
1.概念:同变量类似,程序执行过程中数值不能改变
2.语法:
显式类型定义
隐式类型定义
3.常数
固定的数值: 100 ”abc“
*/
fmt.Println(100)
fmt.Println("abc")
//1.定义常量
const PATH string = "http://www.baidu.com"
const PI = 3.14
fmt.Println(PATH)
fmt.Println(PI)
//2.尝试修改常量的数值
//PATH="http://www.sina.com"
//3.定义一组常量
const C1, C2, C3 = 100, 3.14, "哈哈"
const (
MALE = 0
FEMALE = 1
UNKNOW = 3
)
//4.一组常量中,如果某个常量没有初始值,默认和上一行一致
const (
a int = 100
b
c string = "ruby"
d
e
)
fmt.Printf("%T, %d\n", a, a)
fmt.Printf("%T, %d\n", b, b)
fmt.Printf("%T, %s\n", c, c)
fmt.Printf("%T, %s\n", d, d)
fmt.Printf("%T, %s\n", e, e)
//5.枚举类型,使用常量组作为枚举类型,一组相关数值的数据
const (
SPRING = 0
SUMMER = 1
AUTUMN = 2
WINTER = 3
)
}
常量的注意事项:
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串
不管使用的常量,在编译的时候,是不会报错的。
显示指定类型的时候,必须确保常量左右值类型一致,需要时可做显示类型转换。 这与变量就不一样了,变量是可以是不同的类型值。
三、iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量,iota可以被用做枚举值。
package main
import "fmt"
func main() {
/*
iota:特殊的常量,要以被编译器自动修改的常量
每当定义一个const, iota初始值为0
每当定义一个常量,就会自动累加1
直到下一个const出现,清零
*/
const (
a = iota
b = iota
c = iota
)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
const (
d = iota
e
)
fmt.Println(d)
fmt.Println(e)
//枚举中
const (
male = iota
female
unknow
)
fmt.Println(male, female, unknow)
}
const (
A = iota
B
C
D = "haha"
E
F = 100
G
H = iota
I
)
const (
j = iota
)
fmt.Println(A)
fmt.Println(B)
fmt.Println(C)
fmt.Println(D)
fmt.Println(E)
fmt.Println(F)
fmt.Println(H)
fmt.Println(I)
fmt.Println(j)
三、基本数据类型
1.bool类型
2.数值类型
package main
import "fmt"
func main() {
/*
Go语言的数据类型:
1.基本数据类型
布尔类型: bool
取值: true, false
数值类型:
整数: int
有符号: 最高位表示符号位,0正数,1负数,其余位表示数值
int8: (-128 至 127)
int16: (-32768 至 32767)
int32: (-2147483648 至 2147483647)
int64: (-9223372036854775808 至 9223372036854775807)
无符号:所有的位表示数值
uint8: (0 至 256)
uint16: (0 至 65535)
uint32: (0 至 4294967295)
uint64: (0 至 18446744073709551615)
int uint
byte:uint8
rune:int32
浮点: 生活中的小数
float32, float64
复数: complex
字符串:string
2.复合数据类型
array、slice、 map、 function、 pointer、 struct、 interface、 channel
*/
//1、布尔类型
var b1 bool
b1 = true
fmt.Printf("%T, %t\n", b1, b1)
b2 := false
fmt.Printf("%T, %t\n", b2, b2)
//2.整数
var i1 int8
i1 = 100
fmt.Println(i1)
var i2 uint8
i2 = 200
fmt.Println(i2)
var i3 int
i3 = 1000
fmt.Println(i3)
//语法角度:int , int64 不认为是同一种类型
// var i4 int 64
// i4 == i3 //cannot use i3 (type int) as type int64 in assignment
var i5 uint8
i5 = 100
var i6 byte
i6 = i5
fmt.Println(i5, i6)
var i7 = 100
fmt.Printf("%T, %d\n", i7, i7)
//浮点
var f1 float32
f1 = 103.14
var f2 float64
f2 = 2066.25
fmt.Printf("%T, %f\n", f1, f1) //默认保留六位小数
fmt.Printf("%T, %f\n", f2, f2) //默认保留六位小数
fmt.Printf("%T, %.2f\n", f1, f1) //限制保留两位小数
fmt.Printf("%T, %.3f\n", f2, f2) //限制保留三位小数
fmt.Println(f1) //原样输出
var f3 = 5.12
fmt.Printf("%T, %f\n", f3, f3) //类型推断 float64
}
3.字符串
func string_demo() {
/*
字符串:
1.概念: 多个byte的集合,理解为一个字母序列
2.语法:使用双引号 “abc” "hello" "A" 也可以使用''
3.编码问题: 计算机本质只识别0和1
A:65, B:66,C:67 ....
a:97, b:98, ....
ASCII(美国标准信息交换码)
中国的编码表(gbk) 兼容ASCII
Unicode编码表: 号称统一了全世界
utf-8 utf-16, utf-32 ....
4.转义字符:\
A: 有一些字符,有特殊的作用,可以转义为普通的字符 \' \'
B: 有一些字母,就是普通字母,转义后有特殊的作用 \n, 换行符 \t, 制表符
*/
//1.定义字符串
var s1 string
s1 = "李二毛"
fmt.Printf("%T, %s\n", s1, s1)
s2 := "hello world"
fmt.Printf("%T, %s\n", s2, s2)
//2.区别 'A' "a"
v1 := 'A'
v2 := "A"
fmt.Printf("%T, %d\n", v1, v1)
fmt.Printf("%T,%s\n", v2, v2)
v3 := '中'
fmt.Printf("%T, %d, %q, %c\n", v3, v3, v3, v3)
//3.转义字符
fmt.Println("\"Hello World\"")
//特别的操作
fmt.Println(`He"lloWor"ld`)
fmt.Println("He`lloWor`ld")
}
4.数据类型转换: Type Convert
func type_convert() {
/*
数据类型转换:Type Convert
go语言是静态语言,定义、赋值、运算必须类型一致
语法格式: Type(Value)
注意点:兼容类型可以转换
常量:在有需要的时候,会自动转型
变量:需要手动转型 T(V)
*/
var a int8 = 10
var b int16
b = int16(a)
fmt.Println(a, b)
f1 := 5.12
var c int
c = (int)(f1)
fmt.Println(f1, c)
f1 = float64(a)
fmt.Println(f1)
//b1 := true
//a = int8(b1) //Cannot convert an expression of the type 'bool' to the type 'int8'
}
四、运算符
1.算术运算符
func main() {
/*
算术运算符: +、-、*、/、%、++、--
+ -
*: 乘
/: 取商, 两个数相除,取商
%: 取余, 两个数相除,取余数
++: 自身加1 i++
--:自身减1 i--
++与--相对与整数来计算,不支持 ++i, --i, 及在表达式中运算
*/
a := 10
b := 3
sum := a + b
fmt.Printf("%d + %d = %d\n", a, b, sum)
sub := a - b
fmt.Printf("%d - %d = %d\n", a, b, sub)
mul := a * b
fmt.Printf("%d * %d = %d\n", a, b, mul)
div := a / b
mod := a % b
fmt.Printf("%d / %d = %d\n", a, b, div)
fmt.Printf("%d %% %d = %d\n", a, b, mod)
c := 3
c++
fmt.Println(c)
c--
fmt.Println(c)
}
2.关系运算符
func main() {
/*
关系运算符: >、<、>=、 <=、 ==、 !=
结果总是bool类型的:true、 false
==: 表示比较两个数值是相等的
!=: 表示比较两个数值是不相等的。
*/
a := 3
b := 5
c := 3
res1 := a > b
res2 := b > c
fmt.Printf("%T,%t\n", res1, res1)
fmt.Printf("%T,%t\n", res2, res2)
res3 := a == b
fmt.Println(res3)
res4 := a == c
fmt.Println(res4)
fmt.Println(a != b, b != c)
}
3.逻辑运算符
func main() {
/*
逻辑运算符: 操作数必需是bool, 运算结果也是bool
逻辑与: &&
运算规则:所有的操作数都是真,结果才为真,有一个为假,结果就为假
“一假则假,全真才真”
逻辑或:||
运算规则:所有的操作数都是假,结果才为假,有一个为真,结果就为真
“一真为真,全假才假”
逻辑非: !
!T ---> flase
!F ---> true
*/
f1 := true
f2 := false
f3 := true
res1 := f1 && f2
fmt.Printf("res1: %t\n", res1)
res2 := f1 && f2 && f3
fmt.Printf("res1: %t\n", res2)
res3 := f1 || f2
fmt.Printf("res1: %t\n", res3)
res4 := f1 || f2 || f3
fmt.Printf("res1: %t\n", res4)
fmt.Printf("f1:%t, !f1:%t\n", f1, !f1)
fmt.Printf("f2:%t, !f2:%t\n", f2, !f2)
a := 3
b := 2
c := 5
res5 := a > b && c%a == b && a < (c/b)
fmt.Println(res5)
res6 := b*2 < c || a/b != 0 || c/a > b
fmt.Println(res6)
res7 := !(c/a == b)
fmt.Println(res7)
}
4.位运算符
func main() {
/*
位运算符:
将数值,转为二进制后,按位操作
按位&:
对应位的值如果都为1结果才为1,有一个为0就为0
按位|
对应位的值如果都为0绪果才为0,有一个为1就为1
异或^:
二元:a^b
对应位的值不同为1,相同为0
一元:^a
按位取反:
1 ---> 0
0 ---> 1
位清空:&^
对于 a &^ b
对于b上的每个数值
如果为0, 则取a对应位上的数值
如果为1,则结果位就取0
位移动算符:
<<: 按位左移, 将a转为二进制,向左移动b位
a << b
>>: 按位右移, 将a转为二进制,向右移动b位
a >> b
*/
a := 60
b := 13
/*
60: 0011 1100
13: 0000 1101
&: 0000 1100 12
|: 0011 1101 61
^: 0011 0001 49
&^: 0011 0000 48
^a: 1111 1111 1111 1111 .... 1100 0011
*/
fmt.Printf("a:%d, %b\n", a, a)
fmt.Printf("a:%d, %b\n", b, b)
res1 := a & b
fmt.Println(res1)
res2 := a | b
fmt.Println(res2)
res3 := a ^ b
fmt.Println(res3)
res4 := a &^ b
fmt.Println(res4)
res5 := ^a
fmt.Println(res5)
c := 8
/*
8: 0000 0100
<<: 0001 0000
>>: 0000 0001
*/
res6 := c << 2
fmt.Println(res6)
res7 := c >> 2
fmt.Println(res7)
}
5.赋值运算符
func main() {
/*
赋值运算符:
=,+=,-=, *=, /=, %=, <<=, >>=, &=, |=,^= ...
=: 把=右侧的数值, 赋值给 = 左边的变量
+=, a += b, 相当于 a = a + b
a++ 即 a += 1
*/
var a int
a = 3
fmt.Println(a)
a += 4
fmt.Println(a)
a -= 3
fmt.Println(a)
a *= 2
fmt.Println(a)
a /= 3
fmt.Println(a)
a %= 1
fmt.Println(a)
}
6.优先级运算符优先级
可以通过使用括号来临时提升某个表达式的整体运算优先级。
五、键盘输入输出
import (
"bufio"
"fmt"
"os"
)
func main() {
/*
输入和输出:
fmt包: 输入、输出
输出:
Print() //打印
Println() //打印之后换行
Printf() //格式化打印
格式化打印占位符:
%v 原样输出
%T 打印类型
%t bool类型
%s 字符串
%f 浮点数
%d 10进制的整数
%b 2进制的数
%o 八进制数
%x %X 16进制 %x a-f %X A-F
%c 打印字符
%p 打印地址
输入:
Scanln()
Scanln is similar to Scan,but stops scanning at
scanf()
bufio包
*/
a := 100
b := 3.14
c := true
d := "Hello World"
e := "Ruby"
f := 'A'
fmt.Printf("%T, %b\n", a, a)
fmt.Printf("%T, %f\n", b, b)
fmt.Printf("%T, %t\n", c, c)
fmt.Printf("%T, %s\n", d, d)
fmt.Printf("%T, %s\n", e, e)
fmt.Printf("%T,%d, %c\n", f, f, f)
fmt.Println("__________________________________")
fmt.Printf("%v\n", d)
/*
var x int
var y float64
fmt.Println("请输入一个整数,一个浮点类型:")
fmt.Scanln(&x,&y) //读取键盘的输入,通过操作地址,赋值给x和y,阻塞式
fmt.Printf("a的数值: %d, b的数值; %f\n", a, b)
fmt.Scanf("%d, %f", &x, &y)
fmt.Prinf("x:%d, y:%f\n", x, y)
*/
fmt.Println("请输入一个字符串:")
reader := bufio.NewReader(os.Stdin)
s1, _ := reader.ReadString('\n')
fmt.Println("读到的数据: ", s1)
}
五、流程控制
1.条件语句
(1) if 语句
func main() {
/*
条件语名: if
语法格式: if 条件表达式 {
//
}
*/
//1.指定一个数字,如果大于10,就打印这个数字大于10
num := 16
if num > 10 {
fmt.Println("大于10")
}
//2.给定一个成绩,如果大于等于60分,就打印及格
score := 75
if score > 60 {
fmt.Println("成绩合格")
}
fmt.Println("main...over...")
}
(2) if else 语句
func main() {
/*
if...else语句
if 条件 {50
//条件成立,执行此处的代码.
A 段
}else{
//条件不成立,执行此处的代码:
B 段
}
注意点:
1. if后的{, 一定是要和if条件写在同一行的
2. else一定是if语句}之后,不能自已另起一行
3. if和else中的内容,二者必选其一来执行
*/
//给定一个成绩,如果大于等于60,就是及格,否则就是不及格.
score := 0
fmt.Println("请输入您的成绩:")
fmt.Scanln(&score)
if score >= 60 {
fmt.Println(score, "及格")
} else {
fmt.Println(score, "不及格")
}
sex := "男" //bool, int, string
if sex == "男" {
fmt.Println("可以直接玩字符串")
} else {
fmt.Println("你个死变态")
}
fmt.Println("main...over...")
}
(3) if语句的嵌套
func main() {
/*
if语句的嵌套:
if 条件1 {
A 段
}else {
if 条件2 {
B 段
}else {
C 段
}
}
简写:
if 条件1 {
A 段
}else if 条件2 {
B 段
}else if 条件3 {
C 段
}... else {
n 段
}
*/
sex := "泰国" //bool, int, string
if sex == "男" {
fmt.Println("你因该去男厕所...")
} else {
if sex == "女" {
fmt.Println("正常人")
} else {
fmt.Println("上帝知道")
}
}
}
(4) if语句的其他写法
package main
import "fmt"
func main() {
/*
if语句的其他写法:
if 初始化语句: 条件 {
}
在if中初始化后的作用域在if里
*/
if num := 4; num > 0 {
fmt.Println("正数", num)
} else if num < 0 {
fmt.Println("负数", num)
}
//fmt.Println(num) //Unresolved reference 'num'
num2 := 5
if num2 > 0 {
fmt.Println("num2, 是正数", num2)
}
fmt.Println(num2)
}
2.switch分支语句
(1) switch语句
package main
import "fmt"
func main() {
/*
switch 语句
语法结构:
switch 变量名 {
case 数值1: 分支1
case 数值1: 分支1
case 数值1: 分支1
...
default: 最后一个分支
}
注意事项:
1.switch可以作用在其他类型上,case后的数值必须和switch作用的变量类型一致
2.case是无序
3.case后的数值是唯一的
4.default可选
*/
num := 3
switch num {
case 1:
fmt.Println("第一季度")
case 2:
fmt.Println("第二季度")
case 3:
fmt.Println("第三季度")
case 4:
fmt.Println("第四季度")
default:
fmt.Println("数据错误...")
}
//模拟计算器
num1 := 0
num2 := 0
oper := ""
fmt.Println("请输入一个整数:")
fmt.Scanln(&num1)
fmt.Println("请再输入一个整数:")
fmt.Scanln(&num2)
fmt.Println("请输入一个操作: +,-,*,/")
fmt.Scanln(&oper)
switch oper {
case "+":
fmt.Printf("%d + %d = %d\n", num1, num2, num1+num2)
case "-":
fmt.Printf("%d - %d = %d\n", num1, num2, num1-num2)
case "*":
fmt.Printf("%d * %d = %d\n", num1, num2, num1*num2)
case "/":
fmt.Printf("%d / %d = %d\n", num1, num2, num1/num2)
}
fmt.Println("main...over...")
}
(2) switch其他写法
package main
import "fmt"
func main() {
/*
省略switch后的变量,相当于直接作用在true上
switch { //true;
case true:
case false:
]
case 后可以同时跟随多个数值
switch 变量名 {
case 数值1, 数值2, 数值3: 分支1
case 数值4, 3: 分支2
}
switch后可以多一条初始化语句
switch 初始化语句; 变量 {
}
*/
switch {
case true:
fmt.Println("true...")
case false:
fmt.Println("false...")
}
/*
[0-59]: 不及格
[60, 69]: 及格
[70, 79]: 中等
[80, 89]: 良好
[90, 100]:优秀
*/
score := 88
switch {
case score >= 0 && score < 60:
fmt.Println(score, "不及格")
case score >= 60 && score < 70:
fmt.Println(score, "及格")
case score >= 70 && score < 80:
fmt.Println(score, "中等")
case score >= 80 && score < 90:
fmt.Println(score, "良好")
case score >= 90:
fmt.Println(score, "优秀")
}
fmt.Println("---------------------------------------")
letter := "O"
switch letter {
case "A", "E", "I", "O", "U":
fmt.Println(letter, "是元音....")
case "M", "N":
fmt.Println(letter, "M或N....")
default:
fmt.Println("其他")
}
/*
一个月的天数:
1,3,5,7,8,10,12 31
4,6,9,11 30
2: 29 or 28
*/
month := 9
day := 0
year := 2019
switch month {
case 1, 3, 5, 7, 8, 10, 12:
day = 31
case 4, 6, 9, 11:
day = 30
case 2:
if year%400 == 0 || (year%4 == 0 && year%100 != 0) {
day = 28
} else {
day = 29
}
default:
fmt.Println("月份有误")
}
fmt.Printf("%d 年 %d 月有%d 天\n", year, month, day)
fmt.Println("---------------------------------------")
switch language := "golang"; language {
case "golang":
fmt.Pri