欢迎关注
最酷最in的云资讯

Golang最最最基础语法

这一节看下Golang的基础语法…嘛…如果懒得看的话,记得以下两点就好:
1 Golang的变量、函数参数等等涉及到类型的声明,都是变量名写在前,类型写在后的(和正统C系语法刚好相反)
2 循环语句for通吃所有
然后,就开始啦~

Go语言基本语法

package mainimport (    "fmt")func main() {    fmt.Println("Hello Azen٩(●˙▿˙●)۶…⋆ฺ")}

作用:使用fmt这个库运行输出

定义变量

var 关键字

func variableZeroValueDefine() {    var a int    var s string    fmt.Printf("%d %q\n", a, s)}

知识点:

  1. 变量名写在前面,变量类型写在后面
    原因:在定义变量的时候,往往是先想到名字,再想到变量类型

  2. 定义完变量后,变量都是有默认初值的。
    2.1. int类型的初值为0
    2.2. string类型的初始为空串 – 使用%q可打印空串,展示结果为→ “”

同时定义变量并赋初值

注意:变量定义后,一定要用到,否则编译器报错。

func varibaleInitial() {    var a, b int = 1, 2    var s string = "猜猜我是谁"    fmt.Println(a, b, s)}

此例中,int 和 string是多余的,编译器可以做类型推断 – Type Deduction

类型推断

func varibaleTypeDeduction() {    var a, b, c, s = 1, 2, true, "ㄟ..."    b = 666    fmt.Println(a, b, c, s)}

:=定义并赋初值

更推荐用这种方式定义并初始化变量

func varibaleShortcut() {    a, b := 233, 666    s := "老铁蛤蛤蛤"    fmt.Println(a, b, s)}

在函数外定义变量

var a, b intvar ss = "总想搞个大新闻"

在函数外面定义的变量,不是全局变量,而是包内变量
Go语言木有全局变量的说法。

注意:在函数外定义变量不能用:=的方式,一定要被var关键字修饰

使用()定义多个包内变量

可以把变量定义在括号中,以减少var关键字的使用数量

var (    s string    a, b int    // a, b := 666, 233 // 全局变量不能用:=定义)var ss = "总想搞个大新闻"

内建变量类型

  • bool,string

  • (u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr

    • 没跟长度,则长度按操作系统位数而定

    • uintptr是个指针

  • 字符型

    • byte

    • rune

      • 不是char,char只有1个字节

      • rune的长度为32位,4字节,为应对全球化的字符

  • 浮点数

    • float32,float64

    • complex64,complex128

      • 复数,有实部和虚部

      • complex64的实部和虚部为32位

      • complex128的实部和虚部为64位

      • 把复数直接作为内建变量的类型

强制类型转换

Golang只有强制类型转换,没有隐式类型转换
示例:计算斜边的长度
a = 3 b = 4 求斜边c

func triangle() {    var a, b = 3, 4    var c int    c = int(math.Sqrt(float64(a * a + b * b)))    fmt.Println(c)}

math.Sqrt函数的入参和出参都是float64,所以需要强制转换。

常量的定义

关键字:const
常量类型可规定也可不规定

  • 如果不规定类型,常量会像「文本替换」功能一样(类似宏定义),到使用它的地方再决定类型

Golang中不会把常量全部大写,因为首字母大写在golang中代表作用域为public

func consts() {    const (        filename = "abc.txt"        a, b     = 3, 4    )    var c int    c = int(math.Sqrt(a * a + b * b))    fmt.Println(filename, c)}

*注:上面的a*a就不用强制转为float64,因为被当成类似「宏替换」了

枚举类型

基本定义:就定义成一组const就好

func enums() {    const (        azen  = 0        daker = 1        buran = 2    )    fmt.Println(azen, daker, buran)}

iota自增值

定义枚举

func enums() {    const (        azen  = iota        daker        _        buran    )    fmt.Println(azen, daker, buran)}

iota参与运算

const (    b = 1 << (10 * iota)    kb    mb    gb    tb    pb)

条件语句

if语句

func bounded(v int) int {    if v > 100 {        return 100    } else if v < 0 {        return 0    } else {        return v    }}

特点:if条件不需要用括号包裹
示例:

func ReadFile(filename string) ([]byte, error)

返回两个值:

  • [ ]byte 是读取到的文件内容数组 – 使用%s打印内容

  • error 是出错信息

func fileRead() {    const filename = "abc.txt"    contents, err := ioutil.ReadFile(filename)    if err != nil {        fmt.Println(contents)    } else {        fmt.Println(err)    }}

使用;简化条件

func fileRead() {    const filename = "abc.txt"    if contents, err := ioutil.ReadFile(filename); err != nil {        fmt.Println(contents)    } else {        fmt.Println(err)    }}

在条件中可以用:=做声明和赋值
出了if的作用域就不能访问如上定义的content和err了

switch语句

基本用法

func eval(a, b int, op string) int {    var result int    switch op {    case "+":        result = a + b    case "-":        result = a - b    case "*":        result = a * b    case "/":        result = a / b    default:        panic("不支持的操作类型")    }    return result}

特点:

  • 不需要加break,默认都有break.

  • 如果不需要break,手动加fallthrough – 这一点和swift一样

panic

抛出一个错误 – 类似于NSError的raise

switch后不接表达式

在case中加入条件即可

func grade(score int) string {    var g string    switch {    case score  100:        panic(fmt.Sprintf("Wrong score: %d", score))    case score < 60:        g = "F"    case score < 80:        g = "B"    case score < 90:        g = "A"    case score <= 100:        g = "SSR"    }    return g}

循环语句

for语句

func accumulate() {    sum := 0    for i := 0; i < 100; i++ {        sum++    }    fmt.Println(sum)}

栗子:转二进制

转二进制的思路:不断取模,获得的数字往前加

func convertToBin(number int) string {    result := ""    for ; number > 0; number /= 2 {        lsb := number % 2        result = strconv.Itoa(lsb) + result    }    return result}

strconv.Itoa → 将int转为string

for的while用法(只有结束条件)

func pintFile(filename string) {    file, err := os.Open(filename)    if err != nil {        panic(err)    }     scanner := bufio.NewScanner(file)    //  func (s *Scanner) Scan() bool - 在读完或报错的时候,会返回false    for scanner.Scan() {             }}

当for 语句中,省略其实条件、递增条件,只有结束条件的时候,类似于while

for省略所有表达式 – 死循环

func forever() {    for {        fmt.Println("Bilibili")    }}

Golang中经常要用到死循环,goroutine的肚子里就是死循环。好多死循环的goroutine在互相进行通讯。 – 这和iOS开发中的runloop是一样一样的

函数定义

func eval(a, b int, op string) int

函数名在前,类型在后。和变量定义思路一致

基本示例

func convertToBin(number int) string {    result := ""    for ; number > 0; number /= 2 {        lsb := number % 2        result = strconv.Itoa(lsb) + result    }    return result}

函数返回多个值示例

带余除法

func div(a, b int) (int, int) {    return a / b, a % b}

给返回值起名字

好处是可读性更强,函数调用者可以很方便的知道返回值是啥…

func div(a, b int) (q, r int) {    return a / b, a % b}

如下写法也可以正确返回q和r,但是可读性不强,不建议这样写

func divNoRecommend(a, b int) (q, r int) {    q = a / b    r = a % b    return}

多返回值只使用一个

result, _ := div(10, 7)

多值返回的习惯用法

第一个值返回正常值,第二个值返回error

函数和函数式编程

函数在Golang中是一等公民,函数可以作为参数、返回值

函数作为参数

func apply(op func(a, b int) int, a, b int) (result int)  {    return op(a, b)}

打印下op看看它是谁

  • 拿函数名

    • 需要用reflect.ValueOf(op).Pointer()拿到这个函数的指针

    • 使用runtime获取函数名runtime.FuncForPC(p).Name()

func apply(op func(a, b int) int, a, b int) (result int)  {    p := reflect.ValueOf(op).Pointer()    opName := runtime.FuncForPC(p).Name()    fmt.Println(opName)    return op(a, b)}

匿名函数作为函数参数

fmt.Println(    apply(func (a, b int) int {        return a + b    }, 10, 20),)

Golang没有花哨的lambda表达式

函数其他说明

可变参数列表

可变参数列表的使用方法,可以和数组一样用

func sum(numbers ...int) int {    result := 0    for i := range numbers {        result += numbers[i]    }    return result}

没有默认参数、可选参数概念

指针

func pointerDefine() {    var a = 0    var pa *int = &a    *pa = 0x66CCFF    fmt.Println(a)}

特点

  • 指针不能运算

    • C可以拿到指针的头指针做加法运算 – 步长由指针类型决定

函数参数传递

C、C++、OC可以值传,也可以引用传
Java和Python基本上都是引用传递

Golang只有值传递一种方式

凡调函数,参数都会拷贝一份 – 和指针配合,实现相当引用传递的效果

举例:交换两个变量的值

func swap(a, b *int) {    *a, *b = *b, *a}

作者:Azen
链接:https://www.swifty.cc/p/26ef3f883edd
来源:云微
云微著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

赞(0) 打赏
未经允许不得转载:云微资讯 » Golang最最最基础语法
分享到: 更多 (0)

云微资讯 科技新媒体资讯平台

关于我们联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏