1、变量
变量: 赋值后,可用改变值得标识符
建议采用驼峰法。
var a // 错误的,因为没有右边,go是强类型语言,此时不能使用右边来推导,左边又没有指定类型,所以错误。
var a = 100 //右边无类型常量,缺省雷士是int ,左边a 没有指定类型,用到类型推导,所以a 为int 类型,var a int = 100
var a int // 正确,但是没有赋值,go中正确的原因是 零值可用。 int 的零值是0
案例一:
package main
import (
"fmt"
)
func main() {
var (
a = 100
b int
c string = "abc"
)
fmt.Println(a, b, c)
// var a int ,b string //不支持,批量定义 var()
// var a int, b int 错误
var d, e int // 如果写在一行,必须同类型,只需要在最后指定类型就行
var f, g int = 100,200 //如果要写在一行,必须同类型,只需要在最后指定类型就行,可以赋值,但要全部对于给出值。
fmt.Println(d, e)
}
案例二:
func main() {
a := 100 //赋值语句,段格式变量定义语句,定义变量,定义了变量标识符,右边可以用来推导a 的类型为int
b := "abd"
fmt.Println(a, b)
}
func main() {
a := "100" //赋值语句,段格式变量定义语句,定义变量,定义了变量标识符,右边可以用来推导a 的类型为int
b := "abd"
fmt.Println(a, b)
b = "a"
b = a
fmt.Println(a, b)
}
a := 100 //不能定义全局变量。
{
var a int //零值0
a := 200 //重复定义
a,b := 123, "abcd" //竟然可以,在这里a不能重新定义为新类型,a被检测到了,go语言上只能迁就你了,但是要求a同类型,b是新定义的。
}
{
a,b,c := 123, "abc",12.5 //定义赋值加推导,段格式批量同一行定义,因为短格式不能指定类型,所以采用类型推导,左右要求个数一致。
fmt.Println(a,b,c)
a,b = b,c //为什么是等号,不是变量定义,这是纯粹的赋值;
}
{
var (
m = 111
n = 222
)
// m,n = n,m //交换
tmp := m
m = n
n = tmp
fmt.Println(m,n)
fmt.Println(tmp)
}
// _bank 空白标识符,只能用在左边,其它地方不可以用;
{
a,_ ,c := 123,34 ,567
_ //就是黑洞;
}
_下划线是空白标识符(Blank identifier)
1.1 短格式
- 使用 := 定义变量并立即初始化
- 只能用在函数中,不能用来定义全局变量
- 不能提供数据类型,由编译器来推断;
1.2 零值
零值可用
- int 0
- float 0.0
- bool false
- string 为空串 ”“
- 指针类型为nil
2 标识符本质
每一个标识符对于一个具有数据结构的值,但是这个值不方便直接访问,标识符就是一个指代。
标识符写代码时候,用来指代某个值,编译后还有变量、常量标识符吗? 没有了。。
因为数据在内存中,内存访问靠什么? 地址,标识符编译后就没有了就换成了地址了。
2.1 包级标识符
在Go语言中,在.go文件中的顶层代码中,定义的标识符称为包级标识符。如果首字母大写,可在包外可见。如果首字母小写,则包内可见。
案例一:
//同一个目录就是同一个包,同一个目录里面只能有一个包
package main
import "fmt" //导入包或者第三方包
var a = 100 //全局变量,包内可见,
func main (){ //main函数入口函数,go约定main函数必须在main包中定义
}
顶层代码中定义包级标识符:
-
首字母大写作为包导出标识符,首字母小写作为包内可见标识符
-
const定义包级常量,必须在声明时初始化
-
var定义包级变量
-
可以指定类型,也可以使用无类型常量定义
-
延迟赋值必须指定类型,不然没法确定零值
-
有相关关系的,可以批量定义在一起
一般声明时,还是考虑“就近原则”,尽量靠近第一次使用的地方声明
不能使用短格式定义。
bool在go中不是int类型,也不是其它整数类型。在go中,bool就是布尔型,和整型没有关系,就是完全不同的类型。
3 整型
长度不同:int8、int16(c语言short)、int32、int64
最高位符号位
rune类型本质是int32
长度不同无符号:uint8、uint16、uint32、uint64
u即unsigned,最高位不是符号位
byte类型,它是uint8的别名
Go对类型近乎苛刻的语言,int、uint、int64、uint64,这四个都是完全不同的类型,不能互操作。
有符号,无符号类型:
u unsigned 无符号、以int8、uint8
8bits,总共能表达256中状态。
int 8 ,1 byte ,8 bits,表示正负数,将最高位留出来不能表示数据状态,用1表示负,用0表示正,剩余7位表示数字,能够表示多少个不同的数字呢?256种
uint8,1字节,不能表示负数,所有的8位都用来表示数字
能够表示多少个不同的数字呢? 256种
案例一:
fmt.Printf("%T %T %T %T\n",a,b,c,a+b+c) //format
Printf 往控制台打印,f是format
%T 占位符,和后面的值依次对应
%T 表示type,取值的类型
%d 占位符,数字类型,往往用于整数
%s 用string类型的值
%q 带字符串类型引号的%s ,quote 引号;
%c character 字符输出
%f 占位符,
fmt.Printf("%[1]d %d %[2]d %d ",100,200,300,400) 如果没有指定,是根据上面一个推下来。
值从1开始编 %[index]? 下一个如果没有指定索引,索引默认是index+1
# type
type A int32 //定义新类型
type B = int32 // 类型别名
type rune = int32 类型别名 ,type定义时使用了 = ,你等于我,你就是我,不是新类型,和int32是同一个类型
rune go内建的 ,
type myint int32 // 特别注意这里没有等号 = ,这不是别名,它是个新类型,新和旧类型不是同一个类型。
rune类型,保存的是什么? 字符的unicode码。
强制类型转换:显示 指明 类型转换 ,有可能失败
fmt.Println(a + int(m) ) // int(m)
string (整数值看做是)
强制类型转换: 把一个值从一个类型强制转换到另一种类型,有可能转换失败。
func main () {
var m int64 = 50
fmt.Printf("%T %d\n" ,m,n)
fmt.Printf("%T %s %q\n",sting(m),string(m),string(m)) //string (整数值看做是ascii或unicode码)
fmt.Printf("%T %d\n",rune(m),rune(m)) //type rune= int32 4字节
fmt.Printf("%T %[1]d\n",rune(m)) //通过索引的方式
}
fmt.Printf("%[2]T %[1]d\n",rune(m),stirng(m)) 值从1开始编
fmt.Printf("%[1]d %d %[2]d %d ",100,200,300,400) 如果没有指定,是根据上面一个推下来。
func main() {
var a = '测' // rune int32
fmt.Printf("%T %[1]d %[1]c\n", a) // 27979 rune是int32 是整数,"测”是字面表达,实际计算机存储色是数字
a = 'c' //重新赋值,类型不变 int32 rune
fmt.Printf("%T %[1]d %[1]c\n", a)
a = 99 // unicode 兼容ascii
fmt.Printf("%T %[1]d %[1]c\n", a)
a = '\x63' // \x指16进制字符表示法;
fmt.Printf("%T %[1]d %[1]c\n", a)
}
var m byte = '测' 不可以 爆了
// uint8 int32= >27979 unicode编码不是utf-8
fmt.Println(m)
var m byte = 'a' //ascii表不超过1字节, var m byte = byte('a')
var d byte = '\x61'
可以认为go中没有字符类型,本质上是int32的别名,习惯上称为rune为字符类型
var a int32 = 123 //正确,指定了类型,也赋值。不会采用类型推导,隐式类型转换,语法糖。
var a int32 = int32(123) //
var a = '测' //rune int32
a = 99
//99是字面常量,默认类型是int,a=99 是赋值语句不是定义语句,a类型不变;
// a = int32(99)
只限于 untyped constant;
编程中使用单独类型整型,浮点型、字符串、字符是最多的。
特别注意:字符串是若干字符组成,在内存中使用utf-8编码,而rune只能保存一个字符,输出是unicode
浮点数打印
func main() {
fmt.Println(1000 + 3.6)
fmt.Printf("%f\n", 1000+2.486)
fmt.Printf("%.2f\n", 1000+2.486)
fmt.Printf("%3f\n", 1000+2.486) //打印宽度为3,默认右对齐;
fmt.Printf("%7.1f\n", 1000+2.486) //宽度为7,保留一位小数
fmt.Printf("%-10.1f\n", 1000+2.486) //左对齐
}
4 进制及转换
常见进制有二进制、八进制、十进制、十六进制。应该重点掌握二进制、十六进制。
十进制逢十进一;十六进制分十六进一;二进制逢二进一;
每8位(bit) 为一个字节(byte)
一个字节能够表示的整数的范围。
无符号数0~0xFF ,即0到255,256中状态。
有符号数,依然是256种状态,去掉最到位还剩7位,能够描述的最大正整数为127,那么负数最大就为-128 。也就是说负数有128个,正整数有127个,加0 ,共256种。
^托字符,这表示 幂运算
x进制 => 十进制
1111 1111
f f
二进制到16进制,每4位一断。
二进制到8进制,每3位一断
5 转义字符
每一个都是一个字符,rune类似(int32).可以作为单独字符使用,也可以作为字符串中的一个字符。
\a
\b
\f
\n
\r
\t
\v
\\
\'
\"
问题: 在Go中'\n'和"\n"的区别是什么?
字符和字符串,