标识符
Golang
- 命名规则
0-9_var int int = 30int
- 标识符命名注意事项
- 包名:包名和目录名保持一致,简短有意义
- 变量名:采用驼峰体(第一个单词的首字母小写,其余单词的首字母大写)
- 如果变量名、函数名、常量名的首字母大写,则外部可以访问
保留关键字
总共有25个
预定标识符
总共36个,包含数据基本类型和系统内嵌函数
从终端中获取输入语句
接收用户输入的数据,使用键盘输入语句来获取。
fmtfmtfmt.Scanln()、fmt.Scanf()fmt.Scanln()fmt.Scanf()format
func main(){
var name string
var age byte
var sal float32
var isPass bool
// 1. 使用fmt.Scanln()
fmt.Println("请输入性别 ")
fmt.Scanln(&name) // 引用传递,将地址传过来
fmt.Println("请输入年龄 ")
fmt.Scanln(&age)
fmt.Println("请输入薪水 ")
fmt.Scanln(&sal)
fmt.Println("是否通过考试 ")
fmt.Scanln(&isPass)
fmt.Printf(name, age, sal, isPass)
// 2. 使用fmt.Scanf()
fmt.Println("请输入姓名、年龄、薪水、是否通过考试,使用空格隔开")
fmt.Scanf("%s %d %f %t", &name, &age, &sal, &isPass)
fmt.Printf(name, age, sal, isPass)
}
变量
变量 = 变量名 + 值 + 数据类型
变量声明三种使用方式
运算符
- 算术运算符
func main(){
// 取整函数 / 商
fmt.Println(10/4) // 2
var n1 float32 = 10/4
fmt.Printls(n1) // 2
//保留小小数部分
var n2 float32 = 10.0/4
fmt.Printls(n2) // 2.5
// 取模% 余数
// 公式:a % b = a - a / b * b
fmt.Println(10/3) // 1
fmt.Println(-10%3) // -1
fmt.Println(10/-3) // 1
fmt.Println(-10/-3) // -1
// ++ 和 --
var i int = 10
i++ // i = i + 1 = 11
fmt.Println(i)
i-- // i = i - 1 = 10 上面i已经是11
fmt.Println(i)
// 一个单独的语句,只能独立使用,跟在变量之后
// a = i++ 错误写法
// ++i 错误写法
}
// 练习题
package main()
import "fmt"
func main(){
var days int = 97
var week int = days / 7
var day int = days % 7
fmt.Println("%d个星期0⃣️%d天", week, day)
// 华氏温度转成摄氏温度:5/9(华氏温度-100)
var huashi float32 = 123.3
var sheshi float32 = 5.0 / 9 * (huashi - 100) // 不能写成5/9,这样结果变成了0
fmt.Println("%v 对应的摄氏温度=%v \n", huashi, sheshi)
}
falsetrueforif===
package main
import "fmt"
func test(){
fmt.Println("hello....")
return true
}
func main(){
var i int = 10
if i < 9 && test(){ // 因为i<9已经是false,后面的test函数不会执行,所以什么也不输出
fmt.Println("golang")
}
if i > 9 || test(){ // 因为i>9是true,所以后面的test()不执行,只输出"golang"
fmt.Println("golang")
}
}
计算机内部的计算都是通过二进制的方式进行。
- 按位与&:两个都是1,结果才是1,否则是0
- 按位或|:只要有一个1,结果为1,否则是0
- 按位异或^:一个0,一个1,结果才是1,否则是0
- 左移运算符<<:符号位不变,低位补0
- 右移运算符>>:低位溢出,符号位不变,并用符号位补充溢出的高位
// 3种位运算
func main(){
fmt.Println(2&3) // 00000010 & 00000011 = 00000010=2
fmt.Println(2|3) // 00000010 | 00000011 = 00000011=3
fmt.Println(2^3) // 00000010 ^ 00000011 = 00000001=1
// 先把-2的补码求出来:1111 1110
fmt.Println(-2^2) // 11111110 ^ 00000010 = 11111100(补码)--->11111011(反码)--->10000100(原码)-4
}
- 其他运算符
// & 取地址和 * 取地址中的值
func main(){
a := 100
fmt.Println("a的地址是", &a)
var ptr *int = &a // 将 a 的地址给指针变量 ptr
fmt.Println("ptr 指向的值是=", *ptr)
// 2个数中的最大值
n1 := 10
n2 := 20
var max int
if n1 > n2{
max = n1
}else{
max = n2
}
fmt.Println("2个数中的最大值", max) // 找到2个数中的最大值
// 3个数中的最大值:先求出2个数中的最大值,再和第3个数进行比较
n3 := 45
if n3 > max{
max = n3
}
fmt.Println("3个数中的最大值:", max)
// golang不支持三元运算符
var n int
i := 10
j := 18
if i > j {
n = i
}else {
n = j
}
fmt.Println(n) // 18
}
9 . 原码、反码、补码
二进制的最高位表示符号位,0表示正数,1表示负数。
- 正数的原码、反码、补码都是一样的
- 负数的反码 = 原码符号位不变,其他位取反(0和1取反)
- 负数的补码=反码 + 1
- 0的反码和补码都是0
在计算机中的运算都是通过补码的形式来进行的。
数据类型
bitbytebyte = 8 * bitgoint
- 基本数据类型
- 数值型
- 整数型:int,int8/16/32/64;uint,uint8/16/32/64(1,2,4,8个字节)
- 浮点型:float32(4字节),float64(8字节);可能造成精度损失,64位更精确
- 字符型
- byte:uint8,存储字符选用byte;无符号(0-255)
- rune:int32,处理中文,有符号
- 布尔型bool
- 字符串string
- 数值型
- 派生数据类型
- 指针pointer
- 数组array
- 结构体structure
- 管道Chanel
- 函数function
- 切片slice
- 接口interface
- 映射map
package main
import (
"fmt"
"unsafe"
)
func main(){
var n1 int64
fmt.Printlf("n1 的类型是 %T n1 占用的字节数是 %d", n1, unsafe.Sizeof(n1)) // unsafe.Sizeof() 查看字节数
}
需要注意的地方:
float64Golangfloat64
字符类型
gobytebyteascii
package main
import "fmt"
func main(){
var c1 byte = 'a'
var c2 byte = 'b' // byte范围是0-255
var c3 int = '北' // 超出范围使用int,不能再用byte
var c4 int = 22269 // "国"
var c5 = 10 + 'a' // 107 = 10 + 97
fmt.Println(c1, c2, c3, c4, c5)
}
byteintutf-8Unicode
布尔类型
false true
字符串类型
utf-8unicode
package main
import "fmt"
func main(){
var address string = "北京长城 hello golang"
fmt.Println(address)
// 拼接
var str = "hello" + "golang" // 如果比较长,转行时,需要将加号+放在上行末尾
str += " haha!"
}
- 字符串一旦赋值,就不能被修改
- 双引号可以识别转义字符
- 支持使用反引号``,使得字符串以原生的形式输出,包括换行和特殊字符
- 使用utf-8,解决中文乱码问题
默认值和强制转换
默认值
当数据类型没有被赋值,则使用零值。
- 整型:0
- 浮点型:0
- 字符串:""
- 布尔型:false
转换
go中是强制类型转换,显式转换,不能自动转换。
package main
import "fmt"
func main(){
var i int32 = 100
var j float32 = float32(i) // 强制类型转换
var k int8 = int8(i)
fmt.Println(i, j, k) // i还是int32没有变化
var n1 int32 = 12
var n3 int8
var n4 int8
n4 = int8(n1) + 127 // 编译通过,但是结果不是129,发生溢出问题
// n3 = int8(n1) + 128 编译不通过,128超出int8的范围
}
- 被转换的是变量存储的数据,变量本身的数据类型是没有变化的。
- 范围大—>范围小,编译不会报错,按照溢出处理
基本数据类型—>string
fmt.Sprintf
func main(){
var num1 int = 99
var num2 float64 = 23.5455
var b bool = true
var myChar byte = 'h'
var str string // 空的str
// 1. 通过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)
// 2. strconv
var num3 int = 99
var num4 float64 = 23.5455
var c bool = true
str = strconv.FormatInt(int64(num3), 10)
fmt.Printf("str type %T str=%q\n", str, str)
// 说明:f是转换格式,10是精度,64:float64位
str = strconv.FormatInt(num4, 'f', 10, 64)
fmt.Printf("str type %T str=%q\n", str, str)
str = strconv.FormatBool(c)
fmt.Printf("str type %T str=%q\n", str, str)
// Itoa函数
var num5 int = 345
str = strconv.Itoa(num5) // 参数必须是int类型,如果不是使用int()函数先转换
fmt.Printf("str type %T str=%q\n", str, str)
}
- strconv包中的函数
- FormatInt
- FormatBool
- FormatUint
- FormatFloat
string—>基本数据类型
strconstringGolang
package main
import "fmt"
func main(){
var str string = "true"
var b bool
// 函数有两个值:布尔值和error,关心的是bool
// 下划线 _ 表示忽略
b, _ = strconv.ParseBool(str)
fmt.Printf("b type %T b=%v", b, b)
var str2 string = "1234"
var n1 int64
var n2 int
n1, _ = strconv.ParseInt(str2, 10, 64) // 返回值是64位,所有必须使用64位来接收
n2 = int(n1)
fmt.Printf("n1 type %T n1=%v", n1, n1)
fmt.Printf("n2 type %T n2=%v", n2, n2)
var str3 string = "123.45"
var f1 float64
var f2 float32
f1, _ = strconv.ParseFloat(str3, 64) // float只有32和64两种位数
f2 = float32(f1)
fmt.Printf("f1 type %T f1=%v", f1, f1)
fmt.Printf("f2 type %T f2=%v", f2, f2)
}
指针
&*var ptr *int = &numptr*datatype
func main(){
// 基本数据类型的布局
var i int = 10
// i的地址:&i
fmt.Println(&i)
// 1. ptr是指针类型变量
// 2. ptr的类型是 *int(指针类型)
// 3. ptr本身的值是&i,即 i 的内存地址
var ptr *int = &i
fmt.Printf("ptr=%v\n", ptr)
fmt.Printf("ptr 的地址=%v", &ptr) // 获取地址
fmt.Printf("ptr 指向的值=%v",*ptr) // 获取地址指向的值
}
// 输出地址
package main
import "fmt"
func main(){
var num int = 9
fmt.Printf("num address=%v", &num) // 获取变量的地址
var ptr *int
ptr = &num
*ptr = 10 // 修改会改变num的值
fmt.Println("num=", num)
}
// 指针练习
package main
import "fmt"
func main(){
var a int = 300 // 定义两个int变量
var b int = 400
var ptr *int = &a // 指针变量ptr为a的内存地址,值的指向是a
*ptr = 100 // 将ptr指向的值改为100,则 a=100
ptr = &b // ptr变成b的内存地址
*ptr = 200 // 将ptr指向的值修改为200,b=200
fmt.Printf("a=%d b=%d ptr=%d",a,b,*ptr)
}
值类型和引用类型
int\floatbool\stringarraystructGCpointerslicemapchannelinterface