关于php:go学习笔记1

hello GO

这里应用vscode

  1. 装置插件go
  2. 新建hello文件夹,创立main.go文件

    package main
    import "fmt"
    func main(){
        fmt.Println("Hello")
    }
    1. 关上命令行

  3. 执行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

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语言反对两种浮点型数:float32float64

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(假)两个值。

留神:

  1. 布尔类型变量的默认值为false
  2. Go 语言中不容许将整型强制转换为布尔型.
  3. 布尔型无奈参加数值运算,也无奈与其余类型进行转换。

字符串

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操作

byte和rune类型

字符用单引号(’)包裹起来

  1. nt8类型,或者叫 byte 型,代表了ASCII码的一个字符。
  2. 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. 算术运算符 + - * / %
  2. 关系运算符 == != > >= < <=
  3. 逻辑运算符 && || !
  4. 位运算符

    运算符 形容
    & 参加运算的两数各对应的二进位相与。 (两位均为1才为1)
    \ 参加运算的两数各对应的二进位相或。 (两位有一个为1就为1)
    ^ 参加运算的两数各对应的二进位相异或,当两对应的二进位相异时,后果为1。 (两位不一样则为1)
    << 左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全副左移b位,高位抛弃,低位补0。
    >> 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全副右移b位。
  5. 赋值运算符 = += -= *= /= %= <<= >>= &= |= ^=

流程管制

ifelse

if 表达式1 {
    分支1
} else if 表达式2 {
    分支2
} else{
    分支3
}

for

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 {
    循环体语句
}

for range(键值循环)

switch case

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

goto

通过标签进行代码间的无条件跳转

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(跳出循环)

break语句能够完结forswitchselect的代码块。

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("...")
}

continue(持续下次循环)

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]]
}

留神:

  1. 数组反对 “==“、”!=” 操作符,因为内存总是被初始化过的。
  2. [n]*T示意指针数组,*[n]T示意数组指针 。

切片

一个领有雷同类型元素的可变长度的序列

定义

var name []T

长度/容量

通过应用内置的len()函数求长度,应用内置的cap()函数求切片的容量

len(s), cap(s)
应用make()函数创立结构切片
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共用一个底层数组
切片遍历

遍历形式和数组是统一的

append
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
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

map定义
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("查无此人")
    }
}
map遍历
func main() {
    scoreMap := make(map[string]int)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    scoreMap["娜扎"] = 60
    for k, v := range scoreMap {
        fmt.Println(k, v)
    }
}

遍历map时的元素程序与增加键值对的程序无关。

delete
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)
    }
}
依照指定程序遍历map
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])
    }
}
元素为map类型的切片
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)
    }
}
值为切片类型的map
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 。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理