标识符

Golang
  1. 命名规则
0-9_var int int = 30int
  1. 标识符命名注意事项
  • 包名:包名和目录名保持一致,简短有意义
  • 变量名:采用驼峰体(第一个单词的首字母小写,其余单词的首字母大写)
  • 如果变量名、函数名、常量名的首字母大写,则外部可以访问

保留关键字

总共有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)

}

变量

变量 = 变量名 + 值 + 数据类型

变量声明三种使用方式

运算符

  1. 算术运算符
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
}
  1. 其他运算符
// & 取地址和 * 取地址中的值

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)
}
  1. 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