Go语言开发注意事项
- Go源文件以“go”为扩展名。
- Go应用程序的执行入口是main()方法。
- Go语言严格区分大小写。
- Go语句后不需要加分号
- go语言定义的变量或者import的包如果没有使用到,代码不能通过编译。
Go语言转义字符(escape char)
- \t : 制表位
- \n:换行符
- \ : 一个\
- “:一个”
- \r:一个回车 fmt.Pritln(“1111\r 张飞”)
规范的代码风格
- Go官方推荐使用行注释来注释整个方法和语句。
- 使用一次tab操作,实现缩进,默认整体向右边移动。用shift+tab整体向左移动。
- 或者使用gofmt来进行格式化。 gofmt hello.go
- 运算符两边习惯性各加一个空格。比如 2 + 4 * 5
Go程序的编写、编译、运行。
编写:写源码
编译:go build 源码 =》生成一个二进制可执行文件。
运行:1.对可执行文件直接运行。2.go run 源码。
Go定义
package main
import "fmt"
var j = 2 //全局变量
func main(){
//单一定义 变量不能重复定义
var i1 int = 1
var i2 = 1
i3 := 1
//多变量定义
var n1, n2, n3 int
n1, n2, n3 := 100, "tom", 999
}
Golang的变量如果没有赋初值,编译器会使用默认值,比如int默认值0,string默认值为空串。
str1+str2 字符串拼接
数据类型
-
基本数据类型:
数值型【整数类型(int[有符号,64为系统8个字节], int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, byte)】,浮点类型【float32,float64】。
字符型【没有专门的字符型,使用byte来保存单个字母字符】。
布尔型(bool)。
字符串(string) -
派生/复杂数据类型:
指针(Pointer)
数组
结构体(struct)
管道(Channel)
函数(也是一种类型)
切片(slice)
接口(interface)
maprune等价于int32,表示一个Unicode码
byte等价于uint8,一个字节。当要存储字符时选用byte
整数类型的使用细节
- Golang各整数类型分:有符号和无符号,int uint的大小和系统有关。
- Golang的整型默认声明为int型
- 如何在程序查看某个变量的字节大小和数据类型
- Golang程序中整型变量在使用时,应该遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型。
- bit:计算机中的最小存储单位。byte:计算机中基本存储单元。
//可以输出n1的数据类型和占用字节数
import (
"fmt"
"unsafe"
)
fmt.Printf("n1 的 类型是 %T,占用的字节数是%d", n1, unsafe.Sizeof(n1))
浮点数类型
- float64的精度比float32的要准确。
- Golang浮点型有固定的范围和字段长度,不受具体OS的影响。
- Golang的浮点型默认声明为float64类型。
- 浮点型常量有两种表示形式
十进制数形式:如5.12, .512
科学计数发形式:如5.1234e2 = 5.1234 * 10^2
5.12E-2 = 5.12 / (10^2) - 通常情况下,应该使用float64。
字符类型
- Golang没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。
- 字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的。8个二进制为8位,即一字节。
- 字符常量是用单引号括起来的单个字符。例如:var c1 byte = ‘a’
- Go中允许使用转义字符’\‘来将其后的字符转变为特殊字符型常量
- Go语言的字符使用UTF-8编码。英文占用1字节,汉字占用3字节。
- 在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值
- 可以直接给某个变量赋一个数字,然后按格式化输出使%c,会输出该数字对应的unicoe字符。
- 字符类型可以运算。
布尔类型
- bool类型数据只允许取值为true和false
- bool类型占用1个字节。
- 默认值为false。
字符串类型:string
- 字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
- 字符串变量一旦赋值了,就不能修改了;在Go中字符串是不可变的。
- 字符串的两种表示形式:
(1) 双引号,会识别转义字符
(2)反引号,以字符串的原生形式输出,包络换行和特殊字符。`` - 多行字符串时最后的+号放右边。
var a int
var b float32
var c float64
var isMarried bool
var name string
fmt.Printf("a=%d,b=%v,c=%v,isMarried=%v,name=%v",a,b,c,isMarried,name)
// %v输出对应的值
输出结果为:
a=0,b=0,c=0,isMarried=false,name=
基本数据类型的转换
- Golang和java/c不同,Go在不同类型的变量之间赋值时需要显式转换。也就是说Golang中数据类型不能自动转换。
var i int = 42
var f float64 = float64(i)
- Go中,数据类型的转换可以是从表示范围小 到 表示范围大, 也可以范围大到范围小。
- 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化。
package main
import "fmt"
func main() {
var a int32 = 33
var b int64 = int64(a)
fmt.Printf("%T\n", a)
fmt.Printf("%T\n", b)
}
输出
int32
int64
- 在转换中,比如将int64转成Int8,编译时不会报错,只是转换的结果是按overflow处理,和我们希望的结果不同。
其他转string
package main
import (
"fmt"
"strconv"
)
func main() {
//演示golang中基本数据练习转换成string使用
var num1 int = 99
var num2 float64 = 23.456
var b bool = true
var myChar byte = 'h'
var str string = "sdf"
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)
//第二中方式 strconv 函数
var num3 int = 99
var num4 float64 = 23.456
var b2 bool = true
str = strconv.FormatInt(int64(num3), 10)
// 'f' 格式 10:小数后保留10位 这个小数是float64
str = strconv.FormatFloat(num4, 'f', 10, 64)
str = strconv.FormatBool(b2)
var num5 int64 = 4567
str = strconv.Itoa(int64(num5))
}
结果:
%q输出的带双引号,%s输出的不带双引号
str type string str="99"
str type string str="23.456000"
str type string str="true"
str type string str="h"
golang中string转成基本数据类型
strconv.ParseBool(str)
func ParseBool(str string) (value bool, err error)
strconv.ParseInt(s string, base int, bitSize int) (i int64, err error)
strconv.ParseFloat(s string,bitSize int)(f float64,err error)
strconv.ParseUint
- 在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比如"123"转成一个整数,但是"hello"不能转成一个整数,如果这样做,Golang直接将其转成0。
指针
- 基本数据类型,变量存的就是值,也叫值类型
- 获取变量的地址,用&,比如 var num int,获取num的地址为:&num
- 指针类型,变量存的是一个地址,这个地址指向的空间存的才是值。比如:var ptr *int = &num
- 获取指针类型所指向的值,使用:, 使用ptr获取p指向的值。
package main
import (
"fmt"
)
func main() {
var i int = 10
fmt.Println("i的地址=", &i)
var j *int = &i
fmt.Println("j 的值为", j)
var k int = *j
fmt.Println("k的值为", k)
}
打印结果为:
i的地址= 0xc0000120a8
j 的值为 0xc0000120a8
k的值为 10
package main
import (
"fmt"
)
func main() {
var i int = 10
fmt.Println("i的地址=", &i)
var j *int = &i
fmt.Println("j 的值为", j)
var k int = *j
fmt.Println("k的值为", k)
*j = 11 //通过指针修改i的值
fmt.Println("i的值为", i)
}
打印结果
i的地址= 0xc0000ac058
j 的值为 0xc0000ac058
k的值为 10
i的值为 11
- 值类型,都有对应的指针类型,形式为数据类型,比如int的对应的指针就是int, float32对应的指针类型就是*float32,以此类推。
- 值类型包括:基本数据类型int系列,float系列,bool,string,数组和结构体struct
引用类型
有指针、slice切片、map、管道chan、interface等都是引用类型。
值类型和引用类型使用特点
- 值类型:变量直接存储值,内存通常在栈中分配
- 引用类型:变量存储 的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收
标识符的命名规范
- Golang对各种变量、方法等命名时使用的字符序列成为标识符。
- 凡是自己可以起名字的地方都叫标识符。
- 由26个英文字母大小写,0-9,_组成。
- 数字不可以开头。。
- Golang中严格区分大小写
- 标识符不能包含空格。
- 下划线本身在Go中是一个而特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如;忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用。
- 不能使用系统保留关键字作为标识符,比如if,break等。int float可以编译通过,但是事件中不推荐使用
- 包名:保持package的名字和目录保持一致,尽量采取有意义的包名。
- 变量名、函数名、常量名采取驼峰法
- 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写则只能在本包中使用(可以理解为:首字母大写是共有的,首字母小写是私有的。)。否则会报错。
%的使用
a%b = a-a/b*b
++ --只能独立使用不能将表达式赋值给其他变量。且只能a++不能++a
对于/,它的整数除和小鼠除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。例如:x:19/5,结果是3
逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
二进制赋值运算符
- <<= 左移后赋值
- >>= 右移后赋值
- &= 按位与后赋值
- ^= 按位异或后赋值
- |= 按位或后赋值
例题
有两个变量,a和b,要求将其进行交换,但是不允许使用中间变量,最终打印结果。
package main
import "fmt"
func main() {
var a int = 10
var b int =20
a = a+b
b = a - b
a = a -b
fmt.Printf("a=%v,b=%v",a,b)
}
运算符优先级
- 只有单目运算符、赋值运算符是从右向左结合运算的
- Go语言明确不支持三元运算符
键盘输入语句
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。
步骤:
- 导入fmt包
- 调用fmt包的fmt.Scanln()或fmt.Scanf()
例如:可以从控制台接收用户信息,【姓名,年龄,薪水】
- 使用fmt.Scanln()获取
2)使用fmt.Scanf()获取
package main
import "fmt"
//"strconv"
func main() {
var name string
var age int
var salary float32
var isPass bool
fmt.Scanln(&name)
fmt.Scanln(&age)
fmt.Scanln(&salary)
fmt.Println(name, " ", age, " ", salary)
fmt.Println("输入第二遍:")
fmt.Scanf("%s %d %f %t", &name, &age, &salary, &isPass)
fmt.Println(name, age, salary, isPass)
}
原码、反码、补码
对于有符号的而言:
-
二进制的最高位是符号位:0表示正数,1表示负数
1:0000 0001
-1:1000 0001 -
正数的原码,反码,补码都一样
-
负数的反码=它的原码符号位不变,其它位取反(0->1,1->0)
-
负数的补码=它的反码+1
-
0的反码,补码都是0
-
在计算机运算的时候,都是以补码的方式来运算。