zoukankan      html  css  js  c++  java
  • 不一样的go语言-一样的语法

    前言

      上一篇入门篇算是初识庐山真面目,我们知道了一个go程序的构成,在这里总结一下。

    //包名
    package
    
    //导入包
    import "fmt"
    
    //main方法,程序入口
    func main() {
        //程序主体
        fmt.Println("Hello World!")
    }
    
    

      那么,作为一个经验丰富的程序员,接下来很自然地就是看看它的语法是怎么样的,怎么声明变量、常量,有哪些数据类型,有哪些运算符,有哪些控制语句,有哪些数据结构,怎么使用函数,还有注释、转义等等。

      当然,作为OO,还会涉及如何定义接口、类,如何创建对象。但下面的内容只会对go语法作一个全览,不作深入探究。更多的细节或者我觉得比较有趣的内容留待后面的文章中探讨。比如go的变量声明为什么设计成名字在前类型在后,为什么go没有三元操作符等等。

    行分隔

    一行代表一个语句结束,不需要使用分号结尾。

    同时go源码格式是语言规范的一部分,并提供了 gofmt工具格式化代码,因此团队协作时,不需要担心格式式模板的问题。

    注释

    //单行注释
    /*
    * 块注释
    */
    

    转义

    go语言的转义符是,其他没有什么特别的。

    变量&常量

    //声明整型变量a
    var a int
    //声明整型变量a,并赋初值1
    var a = 1
    //声明整型变量a,并赋初值1
    a := 1
    
    //多变量声明
    var a, b int
    var a, b = 123, 456 //同类型
    c, d := 111, "abc" //不同类型
    var (
        a int
        b string
    )
    
    //声明常量
    const a int = 1
    const b = 1
    const (
        c string = "abc"
        d := 1
    )
    const (
        x = iota //0
        y //1, 自动加1
        z //2, 自动加1
    )
    
    

    可以看出,变量的声明名称在前,类型在后。而对于不同的数据类型或结构,初值及初始化语法有所差别。此差别会在下文中可以看到。

    数据类型

    名称 说明
    布尔类型 bool,值true or false
    数字类型 包括整型(int,uint,uintptr,byte,rune,uint8,uint16,uint32,uint64,int8,int16,int32,int64)、浮点型(float32,float64,complex64,complex128)
    字符类型 即字符串类型,采用UTF-8编码
    派生类型 包括指针,数组,切片,map,结构,通道,函数,接口

    其中数字类型区分了有符号类型、无符号类型,同时还细分了位数。go号称性能高,如果没有这些细分的数据类型,恐怕就不好吹牛B了。

    运算符

    名称 说明
    算术运算符 +, -, *, /, %, ++, --
    关系运算符 ==, !=, >, <, >=, <=
    逻辑运算符 &&, ||, !
    位运算符 &, |, ^(异或), >>, <<
    赋值运算符 =, +=, -=, *=, /=, %=, <<=, >>=, &=,
    其他运算符 &(取地址), *(指针)

    运算符倒没什么特别的,该有的都有,除了三元操作符

    控制语句

    //if语句
    a := 1
    if a == 1 {//if条件是不带括号的,除了复合条件
        fmt.Println("a==1")
    } else if a < 1 {
        fmt.Println("a<1")
    } else {
        fmt.Println("a>1")
    }
    
    //switch语句
    b := "abc"
    switch b {
        case "abc":
            fmt.Println("abc")
        case "xyz":
            fmt.Println("xyz")
        case "hello", "world":
            fmt.Println("Hello World")
        default:
            fmt.Println("unknown")
    }
    
    //type-switch,用于类型判断
    swithc b.(type) {
        case int:
            fmt.Println("int")
        case string:
            fmt.Println("string")
        default:
            fmt.Println("unknown")
    }
    
    //select语句,常用于channel通信
    var c1, c2 chan int
    select {
        case <- c1:
            fmt.Println("c1")
        case <- c2:
            fmt.Println("c2")
        default
            fmt.Println("none")
    }
    //如果没有 default,select语句会从可用的case中公平随机地选择一个,否则阻塞直至某个 case可用
    //case都不可用且有default时,选择default分支
    
    
    //for循环
    for i := 1; i < 10; i++ {
        fmt.Println(i)
    }
    
    i := 1
    for {
        if i >= 10 {
            break
        }
        fmt.Println(i)
        i++
    }
    
    array := [2]int{1,2}
    for index, value := range array {
        fmt.Printf("index: %d, value: %d", index, value)
    }
    

    看起来多了select语句,但少了while语句。但其for语句的可用性显著地高于其他语言。

    数据结构

    //声明指针
    var a *int
    
    //声明int数组
    var array [2]int
    array[0] = 1
    
    var array2 = [3]int{1,2,3}
    var array3 = [...]int{1,2}
    
    //数组访问
    b := array2[0] //第1个元素
    c := array2[1:2] //c = [2]int{2,3}
    d := array2[1:] //d = [2]int{2,3}
    e := array2[:2] //e = [2]int{1,2}
    //数组遍历
    for index, value := range array2 {
        
    }
    
    //_表示忽略返回值
    for _, value := range array2 {
        
    }
    
    //声明切片(相当于Java的List)
    var slice []int //相当于List<Integer>
    slice = make([]int, 2) //相当于new ArrayList<Integer>(2)
    
    var slice2 []int = make([]int, 2)
    slice3 := make([]int, 2)
    
    //切片的访问与数组一样
    
    //声明map
    var map1 map[string]string
    map1 = make(map[string]string, 2) //相当于new HashMap<String, String>(2)
    
    var map2 map[string]string = make(map[string]string, 2)
    map3 := make(map[string]string, 2)
    
    //map 赋值
    map3["a"] = "a"
    map3["b"] = "b"
    
    //map 访问
    ma := map3["a"] //ma = a
    
    //map 遍历
    for key, value := range map3 {
        
    }
    
    //判断元素是否存在
    if exists, value := map3["a"]; exists {
        
    }
    
    //声明 struct,可认为是go语言的类定义
    type House struct {
        Area float32
        Price int64
    }
    
    //struct 构建
    h := House{}
    h.Area = 120.0
    h.Price = 30000
    
    h1 := House{Area: 120.0, Price: 30000}
    

    函数

    package main
    
    import "fmt"
    
    //函数声明
    func foo() string {
        return "bar"
    }
    
    //函数声明2
    func foo2(value string) (string, error) {
        return bar + value, nil
    }
    
    //函数调用
    func main() {
        fmt.Println(foo())
        if r, err := foo2("xyz"); err != nil {
            fmt.Println(r)
        }
    }
    

      到此为止,go的基础语法已经罗列完毕。这些都是绝大多数语言的共性,除了表达方式上有所不同之外,所有的这些元素都是一门编程语言不可或缺的。总的来说,名字在前,类型在后,语句无分号,判断无括号,其他无两样。

      如果说go有什么不一样的话,那确实有许多不一样之处,留待下回细说。

    请关注公众号

    不一样的go语言

  • 相关阅读:
    vscode 的tab空格设置设置为4的方法
    【vue生命周期】- 详解
    javascript中call()、apply()、bind()的用法终于理解
    彻底理解js中this的指向,不必硬背。
    OKR群:为什么说每个程序员都应该有自己的个人OKR
    2019年程序员最值得学习的思维利器——任务分解
    代码之美——《重构》、《代码整洁之道》
    为什么说程序员都应该写一写博客
    我的第一篇博客
    为什么说程序员都应该玩一玩GitHub
  • 原文地址:https://www.cnblogs.com/laud/p/go_syntax.html
Copyright © 2011-2022 走看看