发布于2021-03-14 05:56 阅读(1603) 评论(0) 点赞(15) 收藏(0)
这里使用vscode
安装插件go
新建hello文件夹,创建main.go文件
package main
import "fmt"
func main(){
fmt.Println("Hello")
}
打开命令行
执行go build 这时同目录会创建一个hello.exe的文件(我这里使用的是win电脑)
也可以使用 go build -o aaa.exe 指定文件名
也直接输出可使用 go run main.go
只需要指定目标操作系统的平台和处理器架构即可:
SET CGO_ENABLED=0 // 禁用CGO
SET GOOS=linux // 目标平台是linux
SET GOARCH=amd64 // 目标处理器架构是amd64
然后再执行go build
命令,得到的就是能够在Linux平台运行的可执行文件了。
Mac 下编译 Linux 和 Windows平台 64位 可执行程序:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
Linux 下编译 Mac 和 Windows 平台64位可执行程序:
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
Windows下编译Mac平台64位可执行程序:
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build
//单行注释
/*
多行注释
*/
fmt.Println('打印输出')
一行代码不需加分号
变量声明后必须使用,不使用会报错
缩进没有严格要求
Go语言中标识符由字母数字和_
(下划线)组成,并且只能以字母和_
开头。
25个关键词
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
37个保留词
Constants: true false iota nil
Types: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
Functions: make len cap new append copy close delete
complex real imag
panic recover
声明: var 变量名 变量类型
单个声明
var aaa string
var age int
var iss bool
批量声明
var (
a string
b int
c bool
)
变量初始化: var 变量名 类型 = 表达式
var name string = "aa"
一次初始化多个变量
var name,age = "bb",20
短变量声明(声明并初始化) :=
n:=10
m:=50
匿名变量:用一个下划线_
表示
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在Lua
等编程语言里,匿名变量也被叫做哑元变量。)
func foo() (int, string) {
return 10, "Q1mi"
}
func main() {
x, _ := foo()
_, y := foo()
fmt.Println("x=", x)
fmt.Println("y=", y)
}
注意:
函数外的每个语句都必须以关键字开始(var、const、func等)
:=
不能使用在函数外。
_
多用于占位,表示忽略值。
const a = 'dsadasd'
和变量类似
const (
a string
b int
c bool
)
iota : go语言的常量计数器
iota
在const关键字出现时将被重置为0
const (
n1 = iota //0
n2 //1
n3 //2
n4 //3
)
使用_调过某些值
const (
n1 = iota //0
n2 //1
_
n4 //3
)
iota
声明中间插队
const (
n1 = iota //0
n2 = 100 //100
n3 = iota //2
n4 //3
)
const n5 = iota //0
多个iota
定义在一行
const (
a, b = iota + 1, iota + 2 //1,2
c, d //2,3
e, f //3,4
)
Go语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map、通道(channel)等。
类型 | 描述 |
---|---|
uint8 | 无符号 8位整型 (0 到 255) |
uint16 | 无符号 16位整型 (0 到 65535) |
uint32 | 无符号 32位整型 (0 到 4294967295) |
uint64 | 无符号 64位整型 (0 到 18446744073709551615) |
int8 | 有符号 8位整型 (-128 到 127) |
int16 | 有符号 16位整型 (-32768 到 32767) |
int32 | 有符号 32位整型 (-2147483648 到 2147483647) |
int64 | 有符号 64位整型 (-9223372036854775808 到 9223372036854775807) |
特殊整型
类型 | 描述 |
---|---|
uint | 32位操作系统上就是uint32 ,64位操作系统上就是uint64 |
int | 32位操作系统上就是int32 ,64位操作系统上就是int64 |
uintptr | 无符号整型,用于存放一个指针 |
进制
// 十进制
var a int = 10
fmt.Printf("%d \n", a) // 10
fmt.Printf("%b \n", a) // 1010 占位符%b表示二进制
// 八进制 以0开头
var b int = 077
fmt.Printf("%o \n", b) // 77
// 十六进制 以0x开头
var c int = 0xff
fmt.Printf("%x \n", c) // ff
fmt.Printf("%X \n", c) // FF
Go语言支持两种浮点型数:float32
和float64
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("%f\n", math.Pi)
fmt.Printf("%.2f\n", math.Pi)
}
complex64和complex128
复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64位。
var c1 complex64
c1 = 1 + 2i
var c2 complex128
c2 = 2 + 3i
fmt.Println(c1)
fmt.Println(c2)
Go语言中以bool
类型进行声明布尔型数据,布尔型数据只有true(真)
和false(假)
两个值。
注意:
false
。s1 := "hello"
s2 := "你好"
字符串转义符
转义符 | 含义 |
---|---|
\r |
回车符(返回行首) |
\n |
换行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\' |
单引号 |
\" |
双引号 |
\\ |
反斜杠 |
多行字符串 使用反引号
字符串的常用操作
方法 | 介绍 |
---|---|
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | join操作 |
字符用单引号(’)包裹起来
nt8
类型,或者叫 byte 型,代表了ASCII码
的一个字符。rune
类型,代表一个 UTF-8字符
。当需要处理中文、日文或者其他复合字符时,则需要用到rune
类型。rune
类型实际是一个int32
修改字符串
要修改字符串,需要先将其转换成[]rune
或[]byte
,完成后再转换为string
。无论哪种转换,都会重新分配内存,并复制字节数组。
func changeString() {
s1 := "big"
// 强制类型转换
byteS1 := []byte(s1)
byteS1[0] = 'p'
fmt.Println(string(byteS1))
s2 := "白萝卜"
runeS2 := []rune(s2)
runeS2[0] = '红'
fmt.Println(string(runeS2))
}
强制转换
T(表达式)
T表示要转换的类型。表达式包括变量、复杂算子和函数返回值等.
算术运算符 + - * / %
关系运算符 == != > >= < <=
逻辑运算符 && || !
位运算符
运算符 | 描述 |
---|---|
& | 参与运算的两数各对应的二进位相与。 (两位均为1才为1) |
| | 参与运算的两数各对应的二进位相或。 (两位有一个为1就为1) |
^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1) |
<< | 左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。 |
>> | 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。 |
赋值运算符 = += -= *= /= %= <<= >>= &= |= ^=
if 表达式1 {
分支1
} else if 表达式2 {
分支2
} else{
分支3
}
for 初始语句;条件表达式;结束语句{
循环体语句
}
完整
func forDemo() {
for i := 0; i < 10; i++ {
fmt.Println(i)
}
}
初始语句省略
func forDemo2() {
i := 0
for ; i < 10; i++ {
fmt.Println(i)
}
}
初始语句/结束语句结束
func forDemo3() {
i := 0
for i < 10 {
fmt.Println(i)
i++
}
}
无限循环
for {
循环体语句
}
func switchDemo1() {
finger := 3
switch finger {
case 1:
fmt.Println("大拇指")
case 2:
fmt.Println("食指")
case 3:
fmt.Println("中指")
case 4:
fmt.Println("无名指")
case 5:
fmt.Println("小拇指")
default:
fmt.Println("无效的输入!")
}
}
func testSwitch3() {
switch n := 7; n {
case 1, 3, 5, 7, 9:
fmt.Println("奇数")
case 2, 4, 6, 8:
fmt.Println("偶数")
default:
fmt.Println(n)
}
}
fallthrough
语法可以执行满足条件的case的下一个case,是为了兼容C语言中的case设计的。
func switchDemo5() {
s := "a"
switch {
case s == "a":
fmt.Println("a")
fallthrough
case s == "b":
fmt.Println("b")
case s == "c":
fmt.Println("c")
default:
fmt.Println("...")
}
}
输出:
a
b
通过标签进行代码间的无条件跳转
func gotoDemo2() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 设置退出标签
goto breakTag
}
fmt.Printf("%v-%v\n", i, j)
}
}
return
// 标签
breakTag:
fmt.Println("结束for循环")
}
break
语句可以结束for
、switch
和select
的代码块。
func breakDemo1() {
BREAKDEMO1:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
break BREAKDEMO1
}
fmt.Printf("%v-%v\n", i, j)
}
}
fmt.Println("...")
}
func continueDemo() {
forloop1:
for i := 0; i < 5; i++ {
// forloop2:
for j := 0; j < 5; j++ {
if i == 2 && j == 2 {
continue forloop1
}
fmt.Printf("%v-%v\n", i, j)
}
}
}
var 数组变量名 [元素数量]T
一旦定义,长度不能变
func main() {
var testArray [3]int //数组会初始化为int类型的零值
var numArray = [3]int{1, 2} //使用指定的初始值完成初始化
var cityArray = [3]string{"北京", "上海", "深圳"} //使用指定的初始值完成初始化
fmt.Println(testArray) //[0 0 0]
fmt.Println(numArray) //[1 2 0]
fmt.Println(cityArray) //[北京 上海 深圳]
}
func main() {
var testArray [3]int
var numArray = [...]int{1, 2}
var cityArray = [...]string{"北京", "上海", "深圳"}
fmt.Println(testArray) //[0 0 0]
fmt.Println(numArray) //[1 2]
fmt.Printf("type of numArray:%T\n", numArray) //type of numArray:[2]int
fmt.Println(cityArray) //[北京 上海 深圳]
fmt.Printf("type of cityArray:%T\n", cityArray) //type of cityArray:[3]string
}
func main() {
a := [...]int{1: 1, 3: 5}
fmt.Println(a) // [0 1 0 5]
fmt.Printf("type of a:%T\n", a) //type of a:[4]int
}
func main() {
var a = [...]string{"北京", "上海", "深圳"}
// 方法1:for循环遍历
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
// 方法2:for range遍历
for index, value := range a {
fmt.Println(index, value)
}
}
func main() {
a := [3][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
for _, v1 := range a {
for _, v2 := range v1 {
fmt.Printf("%s\t", v2)
}
fmt.Println()
}
}
北京 上海
广州 深圳
成都 重庆
多维数组只有第一层可以使用...
来让编译器推导数组长度。例如:
//支持的写法
a := [...][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
//不支持多维数组的内层使用...
b := [3][...]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
数组是值类型,赋值和传参会复制整个数组。因此改变副本的值,不会改变本身的值。
func modifyArray(x [3]int) {
x[0] = 100
}
func modifyArray2(x [3][2]int) {
x[2][0] = 100
}
func main() {
a := [3]int{10, 20, 30}
modifyArray(a) //在modify中修改的是a的副本x
fmt.Println(a) //[10 20 30]
b := [3][2]int{
{1, 1},
{1, 1},
{1, 1},
}
modifyArray2(b) //在modify中修改的是b的副本x
fmt.Println(b) //[[1 1] [1 1] [1 1]]
}
注意:
[n]*T
表示指针数组,*[n]T
表示数组指针 。一个拥有相同类型元素的可变长度的序列
var name []T
通过使用内置的len()
函数求长度,使用内置的cap()
函数求切片的容量
len(s), cap(s)
make([]T, size, cap)
T:切片的元素类型
size:切片中元素的数量
cap:切片的容量
a := make([]int, 2, 10)
fmt.Println(a) //[0 0]
fmt.Println(len(a)) //2
fmt.Println(cap(a)) //10
请始终使用len(s) == 0
来判断,而不应该使用s == nil
来判断。
s1 := make([]int, 3) //[0 0 0]
s2 := s1 //将s1直接赋值给s2,s1和s2共用一个底层数组
遍历方式和数组是一致的
func main(){
var s []int
s = append(s, 1) // [1]
s = append(s, 2, 3, 4) // [1 2 3 4]
s2 := []int{5, 6, 7}
s = append(s, s2...) // [1 2 3 4 5 6 7]
}
var声明的零值切片可以在append()
函数直接使用,无需初始化。
s := []int{} // 没有必要初始化
s = append(s, 1, 2, 3)
var s = make([]int) // 没有必要初始化
s = append(s, 1, 2, 3)
追加切片
var citySlice []string
// 追加一个元素
citySlice = append(citySlice, "北京")
// 追加多个元素
citySlice = append(citySlice, "上海", "广州", "深圳")
// 追加切片
a := []string{"成都", "重庆"}
citySlice = append(citySlice, a...)
fmt.Println(citySlice) //[北京 上海 广州 深圳 成都 重庆]
copy(destSlice, srcSlice []T)
srcSlice: 数据来源切片
destSlice: 目标切片
func main() {
// copy()复制切片
a := []int{1, 2, 3, 4, 5}
c := make([]int, 5, 5)
copy(c, a) //使用copy()函数将切片a中的元素复制到切片c
fmt.Println(a) //[1 2 3 4 5]
fmt.Println(c) //[1 2 3 4 5]
c[0] = 1000
fmt.Println(a) //[1 2 3 4 5]
fmt.Println(c) //[1000 2 3 4 5]
}
没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除元素
从切片a中删除索引为index
的元素,操作方法是a = append(a[:index], a[index+1:]...)
func main() {
// 从切片中删除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要删除索引为2的元素
a = append(a[:2], a[3:]...)
fmt.Println(a) //[30 31 33 34 35 36 37]
}
map[KeyType]ValueType
KeyType:表示键的类型。
ValueType:表示键对应的值的类型。
map类型的变量默认初始值为nil,需要使用make()函数来分配内存。语法为:
make(map[KeyType]ValueType, [cap])
func main() {
scoreMap := make(map[string]int, 8)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
fmt.Println(scoreMap)
fmt.Println(scoreMap["小明"])
fmt.Printf("type of a:%T\n", scoreMap)
}
map[小明:100 张三:90]
100
type of a:map[string]int
map也支持在声明的时候填充元素
func main() {
userInfo := map[string]string{
"username": "沙河小王子",
"password": "123456",
}
fmt.Println(userInfo) //
}
value, ok := map[key]
func main() {
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
// 如果key存在ok为true,v为对应的值;不存在ok为false,v为值类型的零值
v, ok := scoreMap["张三"]
if ok {
fmt.Println(v)
} else {
fmt.Println("查无此人")
}
}
func main() {
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
scoreMap["娜扎"] = 60
for k, v := range scoreMap {
fmt.Println(k, v)
}
}
遍历map时的元素顺序与添加键值对的顺序无关。
delete(map, key)
func main(){
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
scoreMap["娜扎"] = 60
delete(scoreMap, "小明")//将小明:100从map中删除
for k,v := range scoreMap{
fmt.Println(k, v)
}
}
func main() {
rand.Seed(time.Now().UnixNano()) //初始化随机数种子
var scoreMap = make(map[string]int, 200)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("stu%02d", i) //生成stu开头的字符串
value := rand.Intn(100) //生成0~99的随机整数
scoreMap[key] = value
}
//取出map中的所有key存入切片keys
var keys = make([]string, 0, 200)
for key := range scoreMap {
keys = append(keys, key)
}
//对切片进行排序
sort.Strings(keys)
//按照排序后的key遍历map
for _, key := range keys {
fmt.Println(key, scoreMap[key])
}
}
func main() {
var mapSlice = make([]map[string]string, 3)
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
}
fmt.Println("after init")
// 对切片中的map元素进行初始化
mapSlice[0] = make(map[string]string, 10)
mapSlice[0]["name"] = "小王子"
mapSlice[0]["password"] = "123456"
mapSlice[0]["address"] = "沙河"
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
}
}
func main() {
var sliceMap = make(map[string][]string, 3)
fmt.Println(sliceMap)
fmt.Println("after init")
key := "中国"
value, ok := sliceMap[key]
if !ok {
value = make([]string, 0, 2)
}
value = append(value, "北京", "上海")
sliceMap[key] = value
fmt.Println(sliceMap)
高颜值后台管理系统免费使用 ### 子枫后台管理系统 ###,可在宝塔面板直接安装
欢迎关注我的公众号:子枫的奇妙世界,获得独家整理的学习资源和日常干货推送。
如果您对我的其他专题内容感兴趣,直达我的个人博客:www.wangmingchang.com 。
原文链接:https://www.cnblogs.com/wmc1125/p/13574132.html
作者:你是好人
链接:http://www.phpheidong.com/blog/article/3217/e2e7d2eb392ab2b53ddc/
来源:php黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 php黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-4
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!