Go 基础

go 介绍

1.静态语言类型,但有动态语言感觉(开发效率高)
2.运行效率高
3.语言层面支持并发
4.丰富的第三方库

适合做
服务器编程

编程

go 语言以包作为管理单位
每个文件必须声明包
程序必须有一个main包

语句结尾无分号

变量赋值初始化

package main

import (
    "fmt"
)

func main() {
    //变量,程序运行期间,可以改变的量

    //1、声明格式   var 变量名 类型, 变量声明了,必须要使用
    //2、只是声明没有初始化的变量,默认值为0
    //3、同一个{}里,声明的变量名是唯一的
    var a int
    fmt.Println("a = ", a)

    //4、可以同时声明多个变量
    //var b, c int

    a = 10 //变量的赋值
    fmt.Println("a = ", a)

    //2、变量的初始化,声明变量时,同时赋值
    var b int = 10 //初始化,声明变量时,同时赋值(一步到位)
    b = 20         //赋值, 先声明,后赋值
    fmt.Println("b = ", b)

    //3、自动推导类型,必须初始化,通过初始化的值确定类型(常用)
    c := 30
    //%T打印变量所属的类型
    fmt.Printf("c type is %T\n", c)
}

打印结果:
a =  0
a =  10
b =  20
c type is int

Println 与 Printf 的区别

package main

import (
    "fmt"
)

func main() {
    a := 10
    //一段一段处理,自动加换行
    fmt.Println("a = ", a)

    //格式化输出, 把a的内容放在%d的位置
    // "a = 10\n" 这个字符串输出到屏幕,"\n"代表换行符
    fmt.Printf("a = %d\n", a)

    b := 20
    c := 30
    fmt.Println("a = ", a, ", b = ", b, ", c = ", c)
    fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
}

打印结果:
a =  10
a = 10
a =  10 , b =  20 , c =  30
a = 10, b = 20, c = 30

匿名变量,Go函数可以返回多个值

package main

import (
    "fmt"
)

//go函数可以返回多个值
func test() (a, b, c int) {
    return 1, 2, 3
}

func main() {
    //  a := 10
    //  b := 20
    //  c := 30

    a, b := 10, 20

    //交换2个变量的值
    var tmp int
    tmp = a
    a = b
    b = tmp
    fmt.Printf("a = %d, b = %d\n", a, b)
    
    i, j := 10, 20
    i, j = j, i
    fmt.Printf("i = %d, j = %d\n", i, j)

    i = 10
    j = 20

    //_匿名变量,丢弃数据不处理, _匿名变量配合函数返回值使用,才有优势
    tmp, _ = i, j
    fmt.Println("tmp = ", tmp)

    var c, d, e int
    c, d, e = test() //return 1, 2, 3
    fmt.Printf("c = %d, d = %d, e = %d\n", c, d, e)

    _, d, e = test() //return 1, 2, 3
    fmt.Printf("d = %d, e = %d\n", d, e)
}

打印结果:
a = 20, b = 10
i = 20, j = 10
tmp =  10
c = 1, d = 2, e = 3
d = 2, e = 3

常量

package main

import "fmt"

func main() {
    //变量:程序运行期间,可以改变的量, 变量声明需要var
    //常量:程序运行期间,不可以改变的量,常量声明需要const

    const a int = 10
    //a = 20 //err, 常量不允许修改
    fmt.Println("a = ", a)

    const b = 11.2 //没有使用:=
    fmt.Printf("b type is %T\n", b)
    fmt.Println("b = ", b)
}

打印结果:
a =  10
b type is float64
b =  11.2

iota 枚举

package main

import "fmt"

func main() {
    //1、iota常量自动生成器,每个一行,自动累加1
    //2、iota给常量赋值使用
    const (
        a = iota //0
        b = iota //1
        c = iota //2
    )
    fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)

    //3、iota遇到const,重置为0
    const d = iota
    fmt.Printf("d = %d\n", d)

    //4、可以只写一个iota
    const (
        a1 = iota //0
        b1
        c1
    )
    fmt.Printf("a1 = %d, b1 = %d, c1 = %d\n", a1, b1, c1)

    //5、如果是同一行,值都一样
    const (
        i          = iota
        j1, j2, j3 = iota, iota, iota
        k          = iota
    )
    fmt.Printf("i = %d, j1 = %d, j2 = %d, j3 = %d, k = %d\n", i, j1, j2, j3, k)
}

打印结果:
a = 0, b = 1, c = 2
d = 0
a1 = 0, b1 = 1, c1 = 2
i = 0, j1 = 1, j2 = 1, j3 = 1, k = 2

字符与字符串的区别,单引号是字符,双引号是字符串

package main

import "fmt"

func main() {
    var ch byte
    var str string

    //字符
    //1、单引号
    //2、字符,往往都只有一个字符,转义字符除外'\n'
    ch = 'a'
    fmt.Println("ch =", ch)

    //字符串
    //1、双引号
    //2、字符串有1个或多个字符组成
    //3、字符串都是隐藏了一个结束符,'\0'
    str = "a" // 由'a'和'\0'组成了一个字符串
    fmt.Println("str = ", str)

    str = "hello go"
    //只想操作字符串的某个字符,从0开始操作
    fmt.Printf("str[0] = %c, str[1] = %c\n", str[0], str[1])
}

打印结果:
ch = 97
str =  a
str[0] = h, str[1] = e

复合类型 complex128

package main //必须有一个main包

import "fmt"

func main() {
    var t complex128 //声明
    t = 2.1 + 3.14i  //赋值
    fmt.Println("t = ", t)

    //自动推导类型
    t2 := 3.3 + 4.4i
    fmt.Printf("t2 type is %T\n", t2)

    //通过内建函数,取实部和虚部
    fmt.Println("real(t2) = ", real(t2), ", imag(t2) = ", imag(t2))
}

打印结果:
t =  (2.1+3.14i)
t2 type is complex128
real(t2) =  3.3 , imag(t2) =  4.4

格式化输出,%v匹配所有类型

package main //必须有一个main包

import "fmt"

func main() {
    a := 10
    b := "abc"
    c := 'a'
    d := 3.14
    //%T操作变量所属类型
    fmt.Printf("%T, %T, %T, %T\n", a, b, c, d)

    //%d 整型格式
    //%s 字符串格式
    //%c 字符个数
    //%f 浮点型个数
    fmt.Printf("a = %d, b = %s, c = %c, d = %f\n", a, b, c, d)
    //%v自动匹配格式输出
    fmt.Printf("a = %v, b = %v, c = %v, d = %v\n", a, b, c, d)
}

打印结果:
int, string, int32, float64
a = 10, b = abc, c = a, d = 3.140000
a = 10, b = abc, c = 97, d = 3.14

基本类型转换

package main //必须有一个main包

import "fmt"

func main() {
    //这种不能转换的类型,叫不兼容类型
    var flag bool
    flag = true
    fmt.Printf("flag = %t\n", flag)

    //bool类型不能转换为int
    //fmt.Printf("flag = %d\n", int(flag))

    //0就是假,非0就是真
    //整型也不能转换为bool
    //flag = bool(1)

    var ch byte
    ch = 'a' //字符类型本质上就是整型
    var t int
    t = int(ch) //类型转换,把ch的值取出来后,转成int再给t赋值
    fmt.Println("t = ", t)
}

打印结果:
flag = true
t =  97

if 语句

package main //必须有一个main包

import "fmt"

func main() {
    s := "123"

    //if和{就是条件,条件通常都是关系运算符
    if s == "123" { //左括号和if在同一行
        fmt.Println("左手一个妹子,右手一个大妈")
    }

    //if支持1个初始化语句, 初始化语句和判断条件以分号分隔
    if a := 10; a == 10 { //条件为真,指向{}语句
        fmt.Println("a == 10")
    }
}

打印结果:
左手一个妹子,右手一个大妈
a == 10

遍历字符串,range 迭代 列表

package main //必须有一个main包

import "fmt"

func main() {

    str := "abc"

    //通过for打印每个字符
    for i := 0; i < len(str); i++ {
        fmt.Printf("str[%d]=%c, ", i, str[i])
    }
    fmt.Println()

    //迭代打印每个元素,默认返回2个值: 一个是元素的位置,一个是元素本身
    for i, data := range str {
        fmt.Printf("str[%d]=%c, ", i, data)
    }
    fmt.Println()

    for i := range str { //第2个返回值,默认丢弃,返回元素的位置(下标)
        fmt.Printf("str[%d]=%c, ", i, str[i])
    }
    fmt.Println()

    for i, _ := range str { //第2个返回值,默认丢弃,返回元素的位置(下标)
        fmt.Printf("str[%d]=%c, ", i, str[i])
    }
    fmt.Println()
}

打印结果:
str[0]=a, str[1]=b, str[2]=c, 
str[0]=a, str[1]=b, str[2]=c, 
str[0]=a, str[1]=b, str[2]=c, 
str[0]=a, str[1]=b, str[2]=c, 

goto 的使用

package main //必须有一个main包

import "fmt"

func main() {
    //goto可以用在任何地方,但是不能夸函数使用
    fmt.Println("1111111111111")

    goto End //goto是关键字, End是用户起的名字, 他叫标签

    fmt.Println("2222222222222")

End:
    fmt.Println("3333333333333")
}

打印结果:
1111111111111
3333333333333

函数,不定参数

package main //必须有一个main包
import "fmt"

func test(args ...int)  {
    for _, data := range args {
        fmt.Printf("%d, ", data)
    }
}

func main() {
    test(1, 2, 3, 4)
}

打印结果:
1, 2, 3, 4,

将不定参数传递到另一个函数
package main //必须有一个main包
import "fmt"

func test(args ...int)  {
    test2(args...)
}

func test2(args ...int){
    for _, data := range args{
        fmt.Printf("%d, ", data)
    }
}

func main() {
    test(1, 2, 3, 4)
}

打印结果:
1, 2, 3, 4,

含有返回值的函数,函数名首字母小写为private,大写为public

package main //必须有一个main包
import "fmt"

//给返回值起一个变量名,go推荐写法
//常用写法
func test(a int, b int) (result int)  {
    result = a + b
    return
}

func main() {
    result := test(11, 22)
    fmt.Println(result)
}

打印结果:
33

泛型,多态

package main //必须

import "fmt"

type FuncType func(int, int) int

//实现加法
func Add(a, b int) int {
    return a + b
}

func Minus(a, b int) int {
    return a - b
}

func Mul(a, b int) int {
    return a * b
}

//回调函数,函数有一个参数是函数类型,这个函数就是回调函数
//计算器,可以进行四则运算
//多态,多种形态,调用同一个接口,不同的表现,可以实现不同表现,加减乘除
//现有想法,后面再实现功能
func Calc(a, b int, fTest FuncType) (result int) {
    fmt.Println("Calc")
    result = fTest(a, b) //这个函数可以后面再实现
    return
}

func main() {
    //a := Calc(1, 1, Add)
    //a := Calc(1, 1, Minus)
    a := Calc(1, 1, Mul)
    fmt.Println("a = ", a)
}

打印结果:
Calc
a =  0

闭包的作用域需要十分注意,对于变量来说,只有闭包还在使用它,这些变量就还会存在。

package main //必须

import "fmt"

//函数的返回值是一个匿名函数,返回一个函数类型
func test02() func() int {
    var x int //没有初始化,值为0

    return func() int {
        x++
        return x * x
    }
}

func main() {
    //返回值为一个匿名函数,返回一个函数类型,通过f来调用返回的匿名函数,f来调用闭包函数
    //它不关心这些捕获了的变量和常量是否已经超出了作用域
    //所以只有闭包还在使用它,这些变量就还会存在。
    f := test02()
    fmt.Println(f()) //1
    fmt.Println(f()) //4
    fmt.Println(f()) //9
    fmt.Println(f()) //16
}

打印结果:
1
4
9
16

defer 的用法,执行顺序:先进后出

package main //必须
import "fmt"


func test(a int){
    result := 100 / a
    fmt.Println(result)
}


func main() {
    defer fmt.Println("1111111111")
    defer fmt.Println("2222222222")

    test(0)
    defer fmt.Println("3333333333")
}

打印结果:
2222222222
1111111111
panic: runtime error: integer divide by zero
goroutine 1 [running]:

defer 与 匿名函数的配合使用

package main //必须
import "fmt"


func main() {
    a := 10
    b := 20

    defer func(a, b int) {
        fmt.Printf("a = %d, b = %d\n", a, b)
    }(10, 20) //()代表调用此匿名函数, 把参数传递过去,已经先传递参数,只是没有调用

    a = 111
    b = 222
    fmt.Printf("外部:a = %d, b = %d\n", a, b)
}

打印结果:
外部:a = 111, b = 222
a = 10, b = 20

Go 函数 变量作用域

局部变量
package main //必须

import "fmt"

func main() {
    定义在{}里面的变量就是局部变量,只能在{}里面有效
    执行到定义变量那句话,才开始分配空间,离开作用域自动释放
    作用域,变量其作用的范围

    //a = 111
    {
        i := 10
        fmt.Println("i = ", i)
    }
    //i = 111

    if flag := 3; flag == 3 {
        fmt.Println("flag = ", flag)
        flag变量范围只在 if 中
    }

     变量 flag 不存在
    //flag = 4
}

切片作为函数参数时是引用传递,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342