Go基础语法(上)
文章目录
- Go基础语法(上)
- 01注释
- 02变量
- 定义
- 初始化
- 打印内存地址
- 变量交换
- 匿名变量
- 变量的作用域
- 03常量
- iota
- 04基本数据类型
- 布尔类型
- 数字类型
- 整型
- 浮点型
- 字符与字符串
- 05数据类型转换
- 06运算符
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 07获取键盘输入
01注释
注释主要的功能就是为了增强代码的可读性,不参与程序的一切功能,G0语言的注释主要分成两类:
- 单行注释
- 多行注释
package main
import "fmt"
/*
*多行注释
这是一个main函数,这是go语言启动的入口
*/
func main() {
//单行注释
//fmt.Println :打印一句话,然后执行完毕且换行
fmt.Println("Hello,World")
fmt.Println("Hello,World")
fmt.Println("Hello,World")
}
写注释是一个十分良好的习惯,我们都应该按照要求给自己代码写好注释,为了自己,也为了他人。很多大公司里也是对注释有严格要求的。
02变量
搞清楚注释之后,接下来我们了解一个程序中十分重要的东西,变量!
在数学概念中,变量表示没有固定值且可改变的数。比如×=1,×=2:
字面上的意思理解:变量就是会变化的量。比如我定一个了一个变量叫做名字,它在Go语言中是这样表示的:这个值既可以是张三,也可以是李四。那么在这里,这个name就是变量。可以变化的量。
package main
import "fmt"
func main() {
//name 变量
var name string = "ikun"
name = "jay"
fmt.Println(name)
//结果jay
}
定义
Go语言是静态类型语言,就是所有的类型我们都需要明确的去定义。
这里先了解strig
,我们用它来表示字符串!
在Go语言中,我们声明一个变量一般是使用var
关键字:
格式如下:
var name type
var 变量名 变量类型
/*
var:代表的是声明变量的关键字,固定写法
name:变量的名字
type:变量的类型
*/
示例代码:
//定义一个数字符串变量 name
var name string
//定义一个数字类型变量 age
var age int
//指针
var a, b *int
//定义多个变量
var (
name string
age int
addr string
)
//string默认值:空
//int默认值: 0
fmt.Println(name, age, addr)
变量的命名规则遵循骆驼命名法,即首个单词小写,每个新单词的首字母大写
var形式的声明语句往往是用于需要显式指定变量类型地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。
当一个变量被声明之后,如果没有显示的给他赋值,系统自动赋予它该类型的零值:
-
整型和浮点型变量的默认值为0和0.0。
-
字符串变量的默认值为空字符串。
-
布尔型变量默认为false。
-
切片、函数、指针变量的默认为nil。
初始化
package main
import "fmt"
func main() {
/**
定义多个变量
*/
var (
name string
age int
addr string
)
name = "jay"
age = 27
addr = "China"
//string默认值:空
//int默认值: 0
fmt.Println(name, age, addr)
}
其实Go语言这里做了一个语法糖:短变量声明且初始化
:=
//:= 自动推导
name := "jay"
age := 27
addr := "China"
package main
import "fmt"
func main() {
//:= 自动推导
name := "jay"
age := 27
addr := "China"
fmt.Println(name, age, addr)
//Printf "%T,%T,%T", ---> 求变量类型
fmt.Printf("%T,%T,%T", name, age, addr)
}
/**
*输出结果:
* jay 27 China
* string,int,string
*/
这是Go语言的推导声明写法,编译器会自动根据右值类型推断出左值的对应类型。
它可以自动的推导出一些类型,但是使用也是有限制的:
-
定义变量,同时显式初始化。
-
不能提供数据类型。
-
只能用在函数内部。不能随便到处定义
因为简洁和灵活的特点,简短变量声明被广泛用于大部分的局部变量的声明和初始化。
注意:由于使用:=
,而不是赋值的=
,因此推导声明写法的左值变量必须是没有定义过的变量。若定义过,将会发生编译错误。
打印内存地址
package main
import "fmt"
func main() {
var num int
num = 100
//取地址符 : &
fmt.Printf("num:%d,内存地址:%p", num, &num)
fmt.Println()
num = 200
fmt.Printf("num:%d,内存地址:%p", num, &num)
}
//num:100,内存地址:0xc0000a6058
//num:200,内存地址:0xc0000a6058
内存地址不变
变量交换
package main
import "fmt"
/*
在编程中,最简单的算法就是变量交换了,一般常见方式就是定义中间变量
var a int = 100
var b int = 200
var t int
t = a
a = b
b = t
fmt.Println(a,b)
但是在Go语言中,就不用中间变量了,如下示例代码:
*/
func main() {
var a int = 100
var b int = 200
b, a = a, b
fmt.Println(a, b)
}
匿名变量
匿名变量的特点是一个下画线”_”
,“_“
本身就是一个特殊的标识符,被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变呈对其它变量进行赋值或运算。使用匿名变量时,只需要在变量声明的地方使用下画线替换即可。例如:
package main
import "fmt"
func test() (int, int) {
return 100, 200
}
func main() {
//a, b := test()
//对象:User 匿名变量
a, _ := test()
fmt.Println(a)
}
在编码过程中,可能会遇到没有名称的变量、类型或方法。虽然这不是必须的,但有时候这样做可以极大地增强代码的灵活性,这些变量被统称为匿名变量。
匿名变量不占用内存空间,不会分配内存。匿名变量与匿名变量之间也不会因为多次声明而无法使用。
变量的作用域
- 局部变量
- 全局变量
03常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量。
常量的定义“const
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
我们可以省略类型说明符type
,因为编译器可以根据变量的值来推断其类型。
- 显式类型定义:
const b string = "abc"
- 隐式类型定义:
const b = "abc"
多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2
示例代码如下:
package main
import "fmt"
func main() {
const URL string = "www.baidu.com" //显式类型定义
const URL2 = "www.baidu.com" //隐式类型定义
const a, b, c = 3.14, false, "ikun"
fmt.Printf(URL)
fmt.Printf(URL2)
}
iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。iota是go语言的常量计数器
iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)
const (
a = iota
b = iota
c = iota
)
第一个iota等于0,每当iota在新的一行被使用时,它的值都会自动加1;所以a=0,b=1,c=2可以简写为如下形式:
const (
//一维常量中,如果某个常量没有初始值,默认和上一行一致
a = iota
b
c
)
04基本数据类型
布尔类型
布尔型的值只能是true
false
下面给出示例代码:
func main() {
//bool 默认值 false
var b1 bool
var b2 bool
b1 = true
b2 = false
fmt.Println(b1, b2)
fmt.Printf("%T,%T", b1, b2)
}
//输出:
true false
bool,bool
数字类型
整型int和浮点型float32、float64,GO语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。
整型
序号 | 类型及描述 |
---|---|
1 | uint8无符号8位整型(0-255) |
2 | uint16无符号16位整型 |
3 | uint32无符号32位整型 |
4 | uint64无符号64位整型 |
5 | int8有符号8位整型(-128-127) |
6 | int16有符号16位整型 |
7 | int32有符号32位整型 |
8 | int64有符号64位整型 |
浮点型
序号 | 类型及描述 |
---|---|
1 | float32IEE-754 32位浮点型数 |
2 | float64IEE-754 64位浮点型数 |
3 | complex6432位实数和虚数 |
4 | complex12864位实数和虚数 |
-
关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
-
尾数数部分可能丢失,造成精度损失。-123.0000901
package main
import "fmt"
func main() {
//定义一个整型
var age int = 18
fmt.Printf("%T,%d\n", age, age)
//定义一个浮点型
//默认6位小数
var money float64 = 3.14
var money1 float64 = 3.19
fmt.Printf("%T,%f\n", money, money)
fmt.Printf("%T,%.2f\n", money, money)
fmt.Printf("%T,%.1f\n", money1, money1)
}
//输出
int,18
float64,3.140000
float64,3.14
float64,3.2
以下是其他更多的数字类型:
序号 | 类型及描述 |
---|---|
1 | byte类似uint8(0-255) |
2 | rune类似int32 |
3 | uint32或64位 |
4 | int与uint同大 |
5 | uintptr无符号整型,用于存放指针 |
字符与字符串
package main
import "fmt"
func main() {
var str string
str = "Hello,ikun"
fmt.Printf("%T,%s\n", str, str)
//单引号 字符, 整型-ASCLL字符码
//拓展:
//所有中国字的编码表:GBK
//全世界编码表:Unicode编码表
v1 := 'A'
v2 := "A"
fmt.Printf("%T,%d\n", v1, v1) //int32,65
fmt.Printf("%T,%s\n", v2, v2)
//编码表ASCLL
//字符串连接 +
fmt.Println("hello" + "world")
//转义字符 \
fmt.Println("hello\"666")
fmt.Println("hello\n666") // \n换行
fmt.Println("hello\t666") // \t制表符
//输出
string,Hello,ikun
int32,65
string,A
helloworld
hello"666
hello
666
hello 666
}
05数据类型转换
valueofTypeB = typeB(valueofTypeA)
func main() {
a := 5.0
b := int(a)
fmt.Printf("%T,%f\n", a, a)
fmt.Printf("%T,%d\n", b, b)
}
//输出
float64,5.000000
int,5
- 整型不能转换为布尔类型
类型转换只能在定义正确的情况下转换成功,例如从一个取值范国较小的类型转换到一个取值范围较大的类型(将int16转换为int32)。当从一个取值范固较大的类型转换到取值范固较小的类型时(将int32转换为int16或将float32转换为int),会发生 精度丢失(截断) 的情况。
06运算符
算术运算符
+ - * / % ++ --
关系运算符
== != > < >= <=
逻辑运算符
&& || !
位运算符
(这里涉及电路问题,偏底层,不详细介绍)
运算符 | 描述 |
---|---|
& | 按位与运算符"&"是双目运算符。都是1结果为1,否则是0 |
| | 按位或运算符"|"是双目运算符。都是0结果为0,否是是1 |
^ | 按位异或运算符"^"是双目运算符。不同则为1,相同为0 |
&^ | 位清空,a&^b,对于b上的每个数值,如果为0,则取a对应位上的数值,如果为1,则取0. |
<< | 左移运算符"<<“是双目运算符。左移n位就是乘以2的次方。其功能把”<<“左边的运算数的各二进位全部左移若干位,由”<<"右边的数指定移动的位数,高位丢弃,低位补0。 |
>> | 右移运算符">>“是双目运算符。右移n位就是除以2的次方。其功能是把”>>“左边的运算数的各二进位全部右移若干位,”>>"右边的数指定移动的位数。 |
具体例子如下:
func main() {
/**
首先了解一下二进制 0 1 逢2进1
1 1
2 10
3 11
4 100
*/
//位运算: 二进制上的 0 false 1 true
// & : 我和你 1 1 结果为 1
// | : 我或你 0 1 结果才为1
//前提:A=60 : 0011 1100
// B=13 : 0000 1101
//---------------------------
// &: 0000 1100 我和你同时满足
// |: 0011 1101 我或你 一个满足即可
// ^: 0011 0001 不同为1 相同为0
// &^: 0011 0000 位清空 对于b上的每个数值,如果为0,则取a对应位上的数值,如果为1,则取0.
// >>:2
// <<: 2
var a uint = 60
var b uint = 13
//位运算
var c uint = 0
c = a & b
//fmt.Println(c)
fmt.Printf("%d,二进制%b", c, c) //12,二进制1100
c = a | b
fmt.Printf("%d,二进制%b", c, c) //61,二进制111101
c = a ^ b
fmt.Printf("%d,二进制%b", c, c) //49,二进制110001
//A=60 : 0011 1100
c = a << 2
fmt.Printf("%d,二进制%b", c, c) // 1111 0000
a = 60
c = a >> 2
fmt.Printf("%d,二进制%b", c, c) // 0000 1111
}
赋值运算符
= += -= *= /= %= <<= >>= &= ^= |=
07获取键盘输入
package main
import "fmt"
func main() {
var x int
var y float64
/**
定义了两个变量 想用键盘来录入这个两个变量
fmt.Println() --> 打印并换行
fmt.Printf() --> 格式化输出
fmt.Print() --> 打印输出
fmt.Scanln() --> 接收输入
fmt.Scanf() --> 接受输入 格式化
fmt.Scan() --> 接受输入
*/
fmt.Println("请输入两个数:1.整数 2.浮点数")
//变量取地址 & 变量
fmt.Scanln(&x, &y)
fmt.Println("x = ", x)
fmt.Println("y = ", y)
}
至此,Go基础语法(上)介绍到此,近期会更新Go基础语法(下)。