Go基础
2019-02-07 本文已影响0人
无尾树袋熊
Go基础
Go与c对比
- Go中的注释与C的注释一样,有多行和单行,细节都一样
- 都是由函数组成的
- 入口函数都是main
- 一个程序只能有一个main函数, 没有main函数程序不能执行.格式:
int main(){
逻辑语句;
} //C语言
fun main(){
逻辑语句;
} //Go fun代表是函数 ()为形参列表 {}为函数体
- 如何往控制台输出内容:
#include <stdio.h>
printf("要输出的内容");//告诉系统去哪找输出函数的实现
import "fmt"//告诉系统去哪找输出函数的实现
fmt.Printf("要输出的内容");//告诉系统要输出什么内容
//例如:
func main() {
fmt.Printf("Hello LNJ\n")
}
- 保存源码的文件:
C保存在.C文件中
Go保存在.go文件中
-
代码的管理方式
- C语言通过文件来管理代码会将不同的功能(模块)的代码,放到不同的文件中, 然后声明.h, 然后include导入.h文件使用对应的代码
- Go语言通过包来管理代码, 会将不同功能(模块)的代码, 放到不同的包中,然后通过import导入包来使用对应的代码
-
在Go语言中,一个文件夹就是一个包
-
注意点:
- 包名要和.go文件所在的文件夹的名称保持一致
- 包名不能重复
-
Go语言每条语句后不用添加分号,但如果两条语句在同一行就必须添加
func main() {
fmt.Printf("Hello LNJ\n")
fmt.Printf("Hello it666\n")
}
func main() {
fmt.Printf("Hello LNJ\n");fmt.Printf("Hello it666\n")
}
- Go语言中import了一个包,没有使用会报错.C语言中不会
- Go语言中定义了变量后没使用会报错
- Go语言中函数的{必须和函数名称在同一行, 否则会报错
- 关键字与C语言一样
- GO语言中程序员自己起的名称就是标识符且只能由数字/字母/_组成, 并且不能以数字开头.与C语言一样(Go语言支持UTF-8,所以可以用中文作为标识符(不推荐))
func main() {
var 整数 int = 666
fmt.Printf("%d\n", 整数)
}
- Go语言中也可以通过sizeof来计算数据类型占用的内存大小
import (
"fmt"
"unsafe"
) //导入unsafe
fmt.Println("int size = ",unsafe.Sizeof(int(0)))
//利用unsafe.Sizeof调用函数
//int类型,会根据当前系统自动调整, 如果系统是64位的,int就会自动变成int64, 如果系统是32位的, int就会自耦单变成int32
- 字符类型:byte相当于C语言中的char, 专门用于保存一个字符.rune本质是int32,专门用于保存一个中文字符(==GO语言默认支持中文,默认按照UTF-8来处理,在UTF-8中一个中文占3个字节,在Windows中一个中文占2个字节,在Linux中一个中文占3个字节,非常不方便做兼容处理==)
fmt.Println("byte size = ", unsafe.Sizeof(byte(0))) //1
fmt.Println("rune size = ", unsafe.Sizeof(rune(0))) //4
变量
- 可以改变的数据称为变量
- 定义变量的意义:告诉操作系统,需要分配多大的空间来存储数据
- 格式:
var 变量名 数据类型:
var num int
- 先定义再初始化,定义的同时初始化
var num int
num = 666
fmt.Printf("%d\n",num)
var num int = 666
fmt.Printf("%d\n",num)
- 如果定义的同时初始化,那么定义变量时,数据类型可以省略.除了可以省略数据类型以外,还可以==利用:=继续省略var==(系统会自动根据赋值推倒变量的类型)
var num = 666
fmt.Printf("%d\n",num)
fmt.Printf("%T\n",num) //%T输出变量的数据类型,输出整型只能用%d
num := 666 //不可以写数据类型和var
fmt.Printf("%d\n",num)
//:=先定义一个变量,不能当作=来使用
- 连续定义变量:
var a, b, c int
a = 666
b = 111
c = 222
var a, b, c int= 10, 20, 30
a, b, c, = 10, 20, 30
//变量组 不能使用:=
var (
a int
b int
c int
)
var(
a = 10
b = 20
c = 30
)
- Go语言中的全局变量,只要定义了,在定义之前和定义之后都可以使用
func testi(){
fmt.Printf(format:"%d\n",value)
}
var value int//全局变量
- Go语言中局部变量的作用域和C语言一样
- Go语言局部,全局变量的生命周期和C语言一样
- Go语言和C语言一样,相同的作用域内,不能出现同名的==局部变量==
- Go语言中相同的作用域内,不能出现同名的==全局变量==(与C语言不一样)
- 全局变量未初始化,C与Go都默认为0.局部变量未初始化,C默认为垃圾数据,Go默认为0
- 局部变量如果没有使用, 编译会报错,全局变量如果没有使用, 编译不会报错
- :=只能用于局部变量,不能用于全局变量
- :=如果用于同时定义多个变量, 会有退化赋值现象(==如果通过:=定义多个变量,但是多个变量中有的变量已经在前面定义过了,那么只会对没有定义过的变量执行:=,而定义过的变量只执行=操作==)
num := 123
num, value := 456, 789
fmt.Printf("%d, %d", num, value)
- 类型转换:Go语言只有显示转换,没有隐式转换
数据类型(被转换的数据)
var num int = 3.14 // 报错
var num int = int(3.14) //不能对常量进行强制转换
var num float64 = 3.14
var value int = int(num) //只能对变量进行转换
fmt.Printf("%d\n",value)
//在Go语言中数据类型必须一样,才能赋值
var num int32 = 666
var value int64 = num //报错
var value int32 = num //正确
//特殊情况
var ch byte = 'a'
var num uint8 = ch
var ch rune = '雪'
var num uint32 = ch //报错
//bool类型不能强转为整型
var flag bool = false
var num int = int(flag) //报错
//整型也可以通过T(v)转换为字符串类型(不推荐)
var num int = 97
var str string = string(num)
- 将基本数据类型转换为字符串类型的方式:
// strconv.FormatXxx()
//1.
var num int = 9
var str string = strconv.FormatInt(int64(num),10)
//第一个参数:需要转换的整数,必须是int64类型的
//第二个参数:转换为多少进制的字符串
fmt.Printf("%s\n",str)
//2.
var num float32 = 3.1234567890123456789
var str string = strconv.FormatFloat(float64(num), 'f', -1, 32)
// 第一个参数:需要转换的小数, 必须是float64类型的
// 第二个参数:按照什么格式转换 'f'小数格式 'e' 指数的格式
// 第三个参数: 保留多少位小数, 传入-1按照原始类型的精度保留
// 第四个参数: 原始类型的标志 float32 --> 32 float64 --> 64
//strconv.Itoa()
var num int64 = 666
var str string = strconv.Itoa(int(num))//无法转换小数
fmt.Printf("%s\n", str)
- 将字符串类型转换为基本数据类型
// 1.strconv.ParseXxx()
var str string = "1001"
num, err := strconv.ParseInt(str, 10, 8)
/*
返回值1:转换后的数值,int64
返回值2:转换成功后返回nil,失败则不是nil
参数1:需要转换的字符串
参数2:被转换的字符串保存为多多少进制的
参数3:要转换为多少位整数(被转换的字符串超出了指定长度会报错)
*/
var str string = "3.1234567890123"
num, err := strconv.ParseFloat(str, 64)
/*
参数1:需要转换的字符串
参数2:转换为单精度还是双精度.32或64
返回值1:转换后的小数
返回值2:转换成功后返回nil,失败则不是nil
*/
// 2.strconv.Atoi()
var str string = "9"//不能转换小数
num, err := strconv.Atoi(str)
函数基础
- 格式:
/*
func 函数名(形参列表)(返回值列表){
逻辑语句
}
*/
func calculate()(int, int){
return 10, 20
}
常量
- 格式:
const 常量名称 数据类型 = 值
/*
注意点:
1.数据类型可以省略,const不能省略
2.定义变量不能用 :=
3.局部变量未使用会报错.定义常量和全局变量未使用不会报错
4.可以连续定义常量
5.常量组中,没有赋值,默认值就是上一行的取值
*/
const num int = 666
const a, b, c int = 10, 20, 30
const a, b, c = 10, 20, 30
//常量组:
const (
a = 10
b = 20
c = 30
)
const (
a = 10
b = 20
c //默认为20
)
const(
a, b = 10, 20
c, d //10 20
)
- 枚举
Go语言没有明确定义枚举的固定写法,企业开发中一般会用常量组的形式表示枚举
/*
const (
枚举元素 = 值
枚举元素 = 值
)
*/
const(
male = 0
female = 1
)
/*
1.iota迭代器,默认从0开始
2.常量组中只要出现了iota,后续的常量都会依次递增1
3.如果常量组中的iota被打断了, 那么就不会继续递增
4.如果常量组中的itoa被打断了, 但是后续又被回复了,那么前面有多少行就会递增多少
*/
const(
male = iota //1
female //2
yao //3
)
const(
male = iota //1
female = 666//666
yao //666
)
const(
male = iota //1
female = 666//666
yao = iota //3
)
输出函数
- fmt.Printf("格式化字符串", 数据列表)
num, value := 10, 20
fmt.Printf("num = %d, value = %d\n",num, value)
- fmt.Println(数据列表) 会自动换行
num, value := 10, 20
fmt.Printf("num = ",num "value = ",value)
输入函数
- fmt.Scanf(格式化字符串,地址列表)
- 如果接收的不是字符串类型(%c),会忽略空格和TAB
var num int;
fmt.Scanf("%d",&num)
- fmt.Scan(地址列表)
- 如果接收的不是字符串类型(%c),会忽略空格和TAB和回车
var num int;
var value int;
fmt.Scan(&value,&num)
- fmt.Scanln(地址列表)
- 如果接收的不是字符串类型(%c),会忽略空格和TAB
var num int;
var value int;
fmt.Scanln(&value,&num)
命令行参数
- Go语言中main函数不接受任何参数,但可以通过其它方式接收
- 导入os包,通过os包的Args属性获取命令行参数
- 注意点:默认会将当前被执行程序的可执行文件的路径传递.无论外界传入的数据类型是什么,os包拿到的都是字符串类型.必须按照顺序传递,少传参会报错
var exePath = os.Args[0] var name = os.Args[1] var age = os.Args[2]
- 导入flag包,通过flag包中的stringVar函数获取
- 少传参,不会报错.不用按照顺序传递参数
var name string /* 参数1:数据保存位置 参数2:用于接收的字段名称(-name = yzf) 参数3:没有传递参数时的默认值 参数4:用户输入--help的时候的提示信息 */ flag.String(&name,"name","默认名称","接收用户名") var age string flag.String(&age,"age","-1","接收用年龄") //通过flag包接收用户输入的命令行参数,还必须将编写好的参数注册到命令行 flag.Parse()
算数运算符
- ++ -- / % * + - 用法与c语言一样
- 注意点:
- 不同类型的常量(字面量)可以运算
- 不同类型的变量不可以直接进行运算
num1 := 10
num2 := 3.0
res1 := num1 / num2 //报错
res2 := float64(num1) / num2
- 注意点: +还可以用于拼接字符串
var str1 string = "lnj"
var str2 string = "it66"
var str3 string = str1 + str2
//只有相同类型才能运算
var res string = "lnj" + 7 //报错
- 注意点:
Go语言中++ --只能写在后面,不能写在前面
num := 1
fmt.Println(num) //1
num++
fmt.Println(num) //2
num--
fmt.Println(num) //1
++num //报错
关系运算符
- Go语言中的关系运算符: > < >= <= == !=
- 注意点:C语言中非零即真,Go中没有这个概念,关系运算符返回的都是true或false
- 优先级:==不用记,记住()最高即可==
res := 10 > 5
fmt.Println(res) //true
逻辑运算符
- C与Go语言的逻辑运算符一样:&& || !
- 注意点:
- Go语言中的逻辑运算符返回值是true或false
- 参与运算的表达式的返回值必须都是布尔类型
- 规则:
&& 一假则假
|| 一真则真
! 真变假,假变真
res1 = (10 > 5)&&(1 > 1) //false
res2 = 1 && 1 //报错,两边都必须是布尔类型
res3 = !0 //报错,必须是布尔类型
res4 = (10 > 5)||(1 > 1) //true
位运算符
- Go与C一样:& | ^ << >> 多了一个^&
- 位运算专门用于计算二进制的
- & 一假则假
- | 一真则真
- ^ 不同为真,相同为假
- .<< 乘以2的左移多少次幂
- .>> 除以2的左移多少次幂
- &^ 逻辑清零(如果b的二进制当前位是1,那么就清零.如果不是1,就保留a对应二进制数据)
a := 6
b := 11
res1 = a & b // 2
res2 = a | b // 15
res3 = a ^ b //13
num := 3
num = num << 2 //12
num = num >> 2 //3
0110 a
&^ 1011 b
-----------
0100
a1 := 6
b1 := 11
res1 := a1 &^ b1 //4
赋值运算符
- Go与C一样: = += *= /= %= &= |= ^= <<= >>= 只不过多了一个&^=
num &^ = 5 // num = num &^ 5
其它运算符
- Go与C一样: &取地址运算符,*访问地址运算符
var num := 10
var p *int
p = &num
fmt.Println(*p)