Go 基本语法

  • Hello World
/**
 *第一行代码 package main 定义了包名。
 *你必须在源文件中非注释的第一行指明这个文件属于哪个包,
 *如:package main。package main表示一个可独立执行的程序,
 *每个 Go 应用程序都包含一个名为 main 的包。
 */
package main

//告诉 Go 编译器这个程序需要使用 fmt 包
import "fmt"
/*
func main() 是程序开始执行的函数。
main 函数是每一个可执行程序所必须包含的,
一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,
那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),
这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,
则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )

go run Hello.go
*/
func main() {
    /*
    变量声明

    第一种,指定变量类型,声明后若不赋值,使用默认值。
    var v_name v_type
    v_name = value

    第二种,根据值自行判定变量类型。
    var v_name = value

    第三种,省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误。
    v_name := value,这种只能在函数体中出现

    // 例如
    var a int = 10
    var b = 10
    c : = 10

    var (  // 这种因式分解关键字的写法一般用于声明全局变量
    a int
    b bool
    )


    */
    fmt.Println("Hello, World!")
}

  • 数据类型
package main

import (
    "fmt"
    "reflect"
    "errors"
)

//定义结构体
type Books struct {
    title string
    author string
    subject string
    book_id int
}

//定义接口
type Phone interface {
    call()
}

//定义结构体
type NokiaPhone struct {
}

/*
  实现接口方法
  方法的签名类似:func printBook( book *Books ) {}
  但是实现接口方法在方法名前面要加结构体对象和结构体类型
 */
func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")
}



func main() {
    /*
    type 可选
    const identifier [type] = value

    常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:
    import "unsafe"
    const (
        a = "abc"
        b = len(a)
        c = unsafe.Sizeof(a)
    )

    在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。
    iota 可以被用作枚举值:
    const (
    a = iota //0
    b = iota //1
    c = iota //2
    )
    简写
    const (
    a = iota
    b
    c
    )
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )

    */
    const a, b, c = 1, false, "str" //多重赋值
    fmt.Println(a, b, c)

    var n [10]int /* n 是一个长度为 10 的数组 */
    var i,j int

    /* 为数组 n 初始化元素 */
    for i = 0; i < 10; i++ {
        n[i] = i + 100 /* 设置元素为 i + 100 */
    }

    /* 输出每个数组元素的值 */
    for j = 0; j < 10; j++ {
        fmt.Printf("Element[%d] = %d\n", j, n[j] )
    }


    var ip *int        /* 指向整型*/
    var fp *float32    /* 指向浮点型 */

    var intp int = 10
    var floatp float32 = 32.0

    ip = &intp
    fp = &floatp

    fmt.Printf("变量地址: %x:%x\n", ip,fp  )

    var  ptr *int

    if ptr != nil {
        fmt.Printf("ptr 的值为 : %x\n", ptr  )
    }

    /*
      type Books struct {
               title string
               author string
               subject string
               book_id int
            }
     */
    var Book1 Books        /* 声明 Book1 为 Books 类型 */

    /* book 1 描述 */
    Book1.title = "Go 语言"
    Book1.author = "www.runoob.com"
    Book1.subject = "Go 语言教程"
    Book1.book_id = 6495407

    /* 打印 Book1 信息 */
    fmt.Printf( "Book 1 title : %s\n", Book1.title)
    fmt.Printf( "Book 1 author : %s\n", Book1.author)
    fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
    fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

    printBook(&Book1)

    /*定义切片
    Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,
    功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,
    在追加时可能使切片的容量增大。

    你可以声明一个未指定大小的数组来定义切片:
    var identifier []type
    定义数组是var balance [10] float32或者var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    也就是说数组,[]中括号里必须要有东西,那怕是省略号
    切片不需要说明长度。
    或使用make()函数来创建切片:
    var slice1 []type = make([]type, len)

    也可以简写为

    slice1 := make([]type, len)
    也可以指定容量,其中capacity为可选参数。
    make([]T, length, capacity)
    这里 len 是数组的长度并且也是切片的初始长度。
    或者s :=[] int {1,2,3 }
     */

    var balance = [...]int {1,2,3 }
    fmt.Println(reflect.TypeOf(balance))

    s :=[] int {1,2,3 }
    fmt.Println(reflect.TypeOf(s))

    s = balance[:]
    int_s := append(s, 4)
    fmt.Println(s,int_s)

    //循环

    //这是我们使用range去求一个slice的和。使用数组跟这个很类似
    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }

    fmt.Println("sum:", sum)
    //在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,
    // 所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。
    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }
    //range也可以用在map的键值对上。
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }
    //range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
    for i, c := range "go" {
        fmt.Println(i, c)
    }

    /*定义map
      声明变量,默认 map 是 nil
      var map_variable map[key_data_type]value_data_type

      使用 make 函数
      map_variable := make(map[key_data_type]value_data_type)
     */

    var countryCapitalMap map[string]string
    /* 创建集合 */
    countryCapitalMap = make(map[string]string)

    /* map 插入 key-value 对,各个国家对应的首都 */
    countryCapitalMap["France"] = "Paris"
    countryCapitalMap["Italy"] = "Rome"
    countryCapitalMap["Japan"] = "Tokyo"
    countryCapitalMap["India"] = "New Delhi"

    /* 使用 key 输出 map 值 */
    for country := range countryCapitalMap {
        fmt.Println("Capital of",country,"is",countryCapitalMap[country])
    }

    /* 查看元素在集合中是否存在 */
    captial, ok := countryCapitalMap["United States"]
    /* 如果 ok 是 true, 则存在,否则不存在 */
    if(ok){
        fmt.Println("Capital of United States is", captial)
    }else {
        fmt.Println("Capital of United States is not present")
    }

    /* 删除Map元素 */
    delete(countryCapitalMap,"France");
    fmt.Println("Entry for France is deleted")

    fmt.Println("删除元素后 map")

    /* 打印 map */
    for country := range countryCapitalMap {
        fmt.Println("Capital of",country,"is",countryCapitalMap[country])
    }

    //异常处理

    /*
        error类型是一个接口类型,这是它的定义:
        type error interface {
            Error() string
        }
     */

    f, e := Sqrt(1)
    fmt.Println(f,e==nil)

    f, e = Sqrt(-1)
    fmt.Println(f,e==nil)

}

/*
    1.不想变量被修改。 如果你不想变量被函数和方法所修改,那么选择类型T。相反,如果想修改原始的变量,则选择*T
    2.如果变量是一个大的struct或者数组,则副本的创建相对会影响性能,这个时候考虑使用*T,只创建新的指针,这个区别是巨大的
    3.(不针对函数参数,只针对本地变量/局部变量)对于函数作用域内的参数,如果定义成T,Go编译器尽量将对象分配到栈上,
      而*T很可能会分配到对象上,这对垃圾回收会有影响
 */
func printBook( book *Books ) {
    fmt.Printf( "Book title : %s\n", book.title);
    fmt.Printf( "Book author : %s\n", book.author);
    fmt.Printf( "Book subject : %s\n", book.subject);
    fmt.Printf( "Book book_id : %d\n", book.book_id);
}

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

推荐阅读更多精彩内容