Loading

2-Golang变量

变量的使用步骤

  • 声明变量
  • 给变量赋值
  • 使用变量
package main

import "fmt"

func main() {
	// 声明变量
	var i int
	
	// 给变量赋值
	i = 10

	// 使用变量
	fmt.Println("i=", i)
}

Golang变量使用的三种方式

  • 第一种:指定变量类型,声明后若不赋值,使用默认值
  • 第二种:根据值自行判定变量类型(类型推导)
  • 第三种:省略var,注意:=左侧的变量不应该是已经声明过的,否则会导致编译错误
func var3declare() {
	// 第一种
	var i int
	fmt.Println("i=", i)

	// 第二种
	var num = 10.11
	fmt.Println("num=", num)

	// 第三种
	name := "tom"
	fmt.Println("name=", name)
}

Golang变量其它特点

  • 在编程中,有时我们需要一次性声明多个变量,Golang也提供这样的语法
  • 如何一次性声明多个全局变量:在go中函数外部定义的变量就是全局变量n1, name, n3 := 100, "tom", 888
  • 变量在声明的区域内数据值可以在同一类型范围内不断变化
  • 变量在同一个作用域(在一个函数或者代码块)内不能重名
  • 变量=变量名+值+数据类型,变量三要素
  • Golang的变量如果没有赋初值,编译器会试用默认值,比如int默认值是0,string默认值是空串,小数默认值是0

程序中+号的使用

  • 当左右两边都是数值类型时,则做加法运算
  • 当左右两边都是字符串,则做字符串拼接
func plusSymbol() {
	var i = 1
	var j = 2
	var r = i + j
	fmt.Println("r=", r)

	str1 := "hello "
	str2 := "world"
	str3 := str1 + str2
	fmt.Println("str3=", str3)
}

Golang数据类型基本介绍

整数类型

  • Golang各整数类型分有符号和无符号,int、uint的大小和系统有关

  • Golang的整型默认声明为int型

  • 如何在程序中查看某个变量的字节大小和数据类型:unsafe.Sizeof(x)

  • Golang程序中整型变量在使用时,遵守保小不保大原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型

  • bit:计算机中最小的存储单位,byte:计算机中基本存储单元;1byte=8bit

func testInt() {
	var i = 1
	fmt.Printf("i的数据类型维:%T\n", i)
	fmt.Printf("i占用的字节数为:%d", unsafe.Sizeof(i))

	var s = "你好"
	fmt.Println(utf8.RuneCountInString(s))
	/*
	unsafe.Sizeof返回的是数据类型的大小,而string在Go中并不是直存类型,它是一个结构体类型
	type StringHeader struct {
		Data uintptr
		Len int
	}
	在64位系统上uintptr和int都是8字节,加起来就16了,结果16
	*/
	fmt.Printf("s的数据类型:%T, 占用的字节数:%d\n", s, unsafe.Sizeof(s))
	// Golang默认编码utf-8,中文在utf-8编码下占用3个字节,结果6
	fmt.Println("s的长度为:", len(s))
	// byte等同于int8,用来处理ASCII字符;rune等同于int32,用来处理Unicode或utf-8字符,结果2
	fmt.Println("s的长度为:", len([]rune(s)))
}

小数类型/浮点型

  • 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位,浮点数都是有符号的,尾数部分可能丢失,造成精度损失,如果保存一个精度高的数,应该选用float64
  • Golang浮点类型有固定的范围和字段长度,不受具体OS的影响
  • Golang的浮点型默认声明为float64类型
  • 浮点型常量有两种表示形式:5.12,.512,5.12e2,5.12E-2
func testFloat() {
	num1 := 5.12
	num2 := .512
	num3 := 5.12e2
	num4 := 5.12E2
	num5 := 5.12E-2
	num6 := 5.12e-2
	fmt.Println(num1, num2, num3, num4, num5, num6)
}

字符类型

  • Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存
  • 字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的,也就是与传统的字符串是由字符组成的不同,Go的字符串由字节组成
  • 如果我们保存的字符在ASCII表的,如[0-1,a-z,A-Z...]直接可以保存到byte
  • 如果我们保存的字符对应码值大于255,这时我们可以考虑使用int类型保存
  • 如果我们需要按照字符的方式输出,这时我们需要格式化输出,即fmt.Printf("%c", c)
  • 字符常量是用单引号括起来的字符,例如:var c1 byte = 'a', va c2 int = '中'
  • Go中允许使用转义字符\将其后的字符转变为特殊字符型常量
  • Go语言的字符使用utf-8编码,英文字母-1个字节,汉字-3个字节
  • 在Go中,字符的本质是一个整数,直接输出时,是该字符对应的utf-8编码的码值
  • 可以直接给某个变量赋值一个数字,然后按格式化输出%c,会输出该数字对应的Unicode字符
  • 字符类型是可以进行运算的,相当于一个整数,因为它都对应由Unicode码
  • 字符型存储:字符>>对应码值>>二进制>>存储;字符型读取:二进制>>码值>>字符>>读取
func testChar() {
	var c1 byte = 'a'
	var c2 byte = '0'
	fmt.Println("c1=", c1)
	fmt.Println("c2=", c2)
	fmt.Printf("c1=%c, c2=%c\n", c1, c2)
	var c3 rune = '北'
	fmt.Printf("c3=%c,c3对应的码值=%d\n", c3, c3)
}
/*
c1= 97
c2= 48
c1=a, c2=0
c3=北,c3对应的码值=21271
*/

布尔类型

  • 布尔类型也叫bool类型,bool类型数据只允许取值true和false
  • bool类型占用1个字节
  • bool类型适用于逻辑运算,一般用于程序流程控制
func testBool() {
	var b = false
	fmt.Println("b=", b)
	fmt.Println("b的占用空间=", unsafe.Sizeof(b))
}

string类型

  • 字符串就是一串固定长度的字符连接起来的字符序列,Go的字符串是由单个字节连接起来的,Go语言的字符串的字节使用utf-8编码标识的Unicode文本
  • Go语言的字符串的字节使用utf-8编码标识的Unicode文本,这样Golang统一使用utf-8编码,中文乱码问题不再会困扰程序员
  • 字符串一旦赋值了,字符串就不能修改了:在Go中,字符串是不可变的
  • 字符串的两种表现形式:双引号,会识别转义字符;反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
  • 当一行字符串太长时,需要使用到多行字符串,可以分行写,但是注意,需要将+保留在上一行
func testString() {
	var str string = "hello world"
	fmt.Println("str=", str)
	str2 := "hello" + "hello" + 
	"world" + "world"
	fmt.Println("str2=", str2)
}

基本数据类型的默认值及相互转换

  • Golang和Java/C不同,Go在不同类型的变量之间赋值时需要显示转换。也就是说Golang中数据类型不能自动转换
  • 表达式T(v)将值v转换为类型T
  • Go中,数据类型的转换可以是从范围小>>范围大,也可以是范围大>>范围小
  • 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化
  • 在转换中,比如将int64转换成int8,编译时不会报错,只是转换的结果按溢出处理,和我们希望的结果不一样,因此在转换时,需要考虑范围
func testChange() {
	var i int32 = 100
	var n1 float32 = float32(i)
	var n2 int8 = int8(i)
	var n3 int64 = int64(i)
	// %v相应值的默认格式
	fmt.Printf("i=%v n1=%v n2=%v n3=%v\n", i, n1, n2, n3)
	fmt.Printf("i type is %T\n", i)
}

基本数据类型和string的转换

  • 基本数据类型>>string:fmt.Sprintf("参数", 表达式),Sprintf根据format参数生成格式化的字符串并返回该字符串
  • 基本数据类型>>string:使用strconv包的函数
  • string>>基本数据类型:使用strconv包的函数
  • 将string类型转换成基本数据类型时,要确保string类型能转换成有效的数据,比如我们可以把"123"转换成一个整数,但是不能把"hello"转换成一个整数,如果这样做,Golang直接将其转换成0,其他类型也是一样的道理:float>>0,bool>>false
func testChangeString() {
	var num1 int = 99
	var num2 float64 = 23.456
	var b bool = true
	var myChar byte = 'h'
	var str string
	// Sprintf根据format参数生成格式化的字符串并返回该字符串
	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)
	fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

	var num7 int = 99
	var num8 float64 = 23.45645233431232
	var b2 bool = true
	// 转换为10进制>>string
	str = strconv.FormatInt(int64(num7), 10)
	fmt.Printf("str type %T str=%q\n", str, str)
	/*
	func FormatFloat(f float64, fmt byte, prec, bitSize int) string
	bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。
	fmt表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指数为二进制)、'e'(-d.dddde±dd,十进制指数)、
	'E'(-d.ddddE±dd,十进制指数)、'g'(指数很大时用'e'格式,否则'f'格式)、
	'G'(指数很大时用'E'格式,否则'f'格式)。
	prec控制精度(排除指数部分):对'f'、'e'、'E',它表示小数点后的数字个数;对'g'、'G',
	它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。
	*/
	str = strconv.FormatFloat(num8, 'f', 10, 64)
	fmt.Printf("str type %T str=%q\n", str, str)
	str = strconv.FormatBool(b2)
	fmt.Printf("str type %T str=%q\n", str, str)
	fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

	var str3 string = "true"
	var b3 bool
	// 第一个返回值保存转换后的值,第二个返回值判断是否转换成功。
	b3, _ = strconv.ParseBool(str3)
	fmt.Printf("b type %T b=%v\n", b3, b3)
	var str2 string = "1234556"
	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 str4 string = "1234.345"
	var f1 float64
	f1, _ = strconv.ParseFloat(str4, 64)
	fmt.Printf("f1 type %T f1=%v\n", f1, f1)
}

指针

  • 基本数据类型,变量存的就是值,也叫值类型
  • 获取变量的地址,用&,比如:var num int,获取num的地址:&num
  • 指针类型,指针变量存的是一个地址,这个地址指向的空间才是值
  • 获取指针类型所指向的值,使用:*,比如:var ptr *int,使用*ptr获取ptr指向的值
  • 值类型,都有对应的指针类型,形式为*数据类型,比如int的对应的指针就是*int,float32对应的指针类型就是*float3,以此类推
  • 值类型包括:基本数据类型int系列,float系列,bool,string,数组和结构体struct
func testPointer() {
	var i int = 10
	fmt.Println("i的地址=", &i)

	// ptr是一个指针变量,ptr的类型是*int,ptr本身的值是&i
	var ptr *int = &i
	fmt.Printf("ptr=%v\n", ptr)
	fmt.Printf("prt的地址=%v\n", &ptr)
	// 使用*ptr获取ptr指向的值
	fmt.Printf("ptr指向的值=%v\n", *ptr)

	fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
	var num int = 9
	fmt.Printf("num address=%v\n", &num)
	var ptr2 *int
	// ptr2存num的地址,该地址指向9
	ptr2 = &num
	// 修改ptr2指向的值
	*ptr2 = 10
	fmt.Printf("num=%v\n", num)
}

值类型和引用类型

  • 值类型包括:基本数据类型int系列,float系列,bool,string,数组和结构体struct;变量直接存储值,内存通常在栈中分配
  • 引用类型:指针、slice切片、map、管道channel、interface等都是引用类型;变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收

标识符的命名规范

  • golang对各种变量、方法、函数等命名时使用的字符序列称为标识符,凡是自己可以起名字的地方都叫标识符
  • 标识符由26个英文字母大小写,0-9,_组成,数字不可以开头,Golang中严格区分大小写,标识符不能含空格
  • 下划线_本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其他的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用
  • 不能以系统保留关键字作为标识符(一共25个)
  • 包名:保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库冲突
  • 变量名、函数名、常量名:采用驼峰法
  • 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公开的,首字母小写则是私有的),在Golang中没有public,private等关键字
  • 系统保留关键字

  • 系统的预定义标识符

  • GOPATH下的src默认帮忙添加,因此引入自定义包,只需从src的下一级目录开始即可

posted @ 2022-04-04 01:23  lotuslaw  阅读(62)  评论(0编辑  收藏  举报