Go语法|青训营笔记

36 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

通过简介,我了解到golang作为一门Google公司开发的新兴语言,近些年来发展迅速,尤其在服务端的高并发方面,因此获得IT名企的青睐。

入门

第一部分,我主要在自己事先搭建好的goland开发环境上对基本语法进行操作

Go语言的代码通过(package)组织,包类似于C/C++里的库(libraries)

每个源文件都以一条package声明语句开始,这个例子里就是package main,表示该文件属于哪个包,紧跟着一系列导入(import)的包,之后是存储在这个文件里的程序语句。

//输入输出
package main

import "fmt"

func main(){
    fmt.Println("hello,world")
}

输入输出

  • 常见输入(fmt.Scan(& ),fmt.Scanln(& ),fmt.Scanf("% ",& ))

遇到space,talbe,Enter自动结束读入,若在开始时输入则不会读取

  • 常见输出(print,fmt.Println,fmt.Printf("% ", ))

fmt.Println输出结束后会自动换行

var s string = "hello,world"
print(s, "\n")
fmt.Println(s)
fmt.Printf("%s", s)
//output:
hello,world
hello,world
hello,world

格式控制符

  • %c对应单个字符
  • %q对应带单引号的单个字符
  • %s对应字符串
  • %t对应布尔型
  • %d对应整型
  • %f,%g对应浮点型
package main

import "fmt"

func main() {
   var s = "hello,world"
   for i := 0; i < len(s); i++ {
      fmt.Printf("%c", s[i])
   }
   print("\n")
   for i := 0; i < len(s); i++ {
      fmt.Printf("%q", s[i])
   }
   print("\n")
   fmt.Printf("%s", s)
}
//output:
hello,world
'h''e''l''l''o'',''w''o''r''l''d'
hello,world

变量

声明和赋值

  • Go语言主要有四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数。实体对象的声明 var的声明如下
var 变量名字 类型 = 表达式
  • 其中“类型”或“= 表达式*”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息(隐式赋值)。如果初始化表达式被省略,那么将用零值初始化该变量。
  • 在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导。
package main

import "fmt"

func main() {
   var a = "hello,world"
   var b string = "hello,world"
   c := "hello,world"
   fmt.Println(a, b, c)
}
  • 和变量声明一样,我们可以用下划线空白标识符_来丢弃不需要的值。
_, err = io.Copy(dst, src) // 丢弃字节数
_, ok = x.(T)              // 只检测类型,忽略具体值

类型

  • 一个类型声明语句创建了一个新的类型名称,和现有类型具有相同的底层结构。新命名的类型提供了一个方法,用来分隔不同概念的类型,即使这样它们底层类型相同也是不兼容的。
package main

import "fmt"

type Celsius float64
type Fahrenheit float64

func main() {
   var c Celsius
   var f Fahrenheit
   fmt.Println(c == 0)          // "true"
   fmt.Println(f >= 0)          // "true"
   fmt.Println(c == f)          // compile error: type mismatch
   fmt.Println(c == Celsius(f)) // "true"!
}

指针

  • 一个变量对应了变量对应类型值的内存空间。
  • 一个指针的值是一个变量的地址,一个指针对应变量在内存中的存储位置。
  • 不是每一个值都会有一个内存地址,但是对于每一个变量必然有对应的内存地址。

如果用“var x int”声明语句声明一个x变量,那么&x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,指针对应的数据类型是*int,指针被称之为“指向int类型的指针”。如果指针名字为p,那么可以说“p指针指向变量x”,或者说“p指针保存了x变量的内存地址”。同时*p表达式对应p指针指向的变量的值。一般*p表达式读取指针指向的变量的值,这里为int类型的值,同时因为*p对应一个变量,所以该表达式也可以出现在赋值语句的左边,表示更新指针所指向的变量的值。

package main

func a() *int {
   var x = 10
   return &x
}
func b(x *int) {
   *x++
}
func main() {
   var y = 10
   print(a())
   b(&y)
   print(y, "\n")
}

复合数据

数组

数组是一个由固定长度的特定类型元素组成的序列

var a [3]int             // array of 3 integers
fmt.Println(a[0])        // print the first element
fmt.Println(a[len(a)-1]) // print the last element, a[2]

// Print the indices and elements.
for i, v := range a {
    fmt.Printf("%d %d\n", i, v)
}

// Print the elements only.
for _, v := range a {
    fmt.Printf("%d\n", v)
}

未被赋值则初始化为0

var q [3]int = [3]int{1, 2, 3}
var r [3]int = [3]int{1, 2}
fmt.Println(r[2]) // "0"

可以通过"..."表示数组长度是根据初始化元素个数来确定

q := [...]int{1, 2, 3}
fmt.Printf("%T\n", q) // "[3]int"

slice

可变长序列,序列中每个元素都有相同类型

package main

import "fmt"

func main() {
   s := make([]string, 3)
   s[0] = "hello"
   s[1] = ","
   s[2] = "world"
   fmt.Println(s[0], len(s)) //output:hello 3
   s = append(s, "Guangdong", "Winnerway")
   fmt.Println(s)
   for i, j := range s {
      fmt.Println(i, j)
   }
   index := 2
   s = append(s[:index], s[index+1:]...) //若添加的是切片,则需要“...”来逐个追加
   fmt.Println(s)
}
/*
output:
hello 3
[hello , world Guangdong Winnerway]
0 hello
1 ,
2 world
3 Guangdong
4 Winnerway
[hello , Guangdong Winnerway]
*/

map

即为常见哈希表

package main

import "fmt"

func main() {
   m := make(map[string]string)
   //add
   m["hello"] = "world"
   m["Guangdong"] = "Winnerway"
   m["where"] = "what"
   //change
   m["where"] = "who"
   //delete
   delete(m, "where")
   //find
   fmt.Println(m["Guangdong"], m["hello"])//output:Winnereway world
   r, ok := m["where"]
   print(r, ok)//output:false(由于r为空,将不会打印任何东西)
}

struct

package main

import "fmt"

type user struct {
   id   int
   name string
}

func main() {
   a := user{id: 9, name: "Yi"}
   b := user{9, "Yi"}
   c := user{id: 9}
   c.name = "Yi"
   fmt.Println(a, b, c) //output:{9 Yi} {9 Yi} {9 Yi}
}

json

JavaScript对象表示法(JSON)是一种用于接收和发送结构化信息的标准协议,应用最为广泛的一种协议。这些基础类型可以通过JSON的数组和对象类型进行递归组合。一个JSON数组是一个有序的值序列,写在一个方括号中并以逗号分隔;一个JSON数组可以用于编码Go语言的数组和slice。一个JSON对象是一个字符串到值的映射,写成一系列的name:value对形式,用花括号包含并以逗号分隔;JSON的对象类型可以用于编码Go语言的map类型(key类型是字符串)和结构体。

boolean         true
number          -273.15
string          "She said \"Hello, BF\""
array           ["gold", "silver", "bronze"]
object          {"year": 1980,
                 "event": "archery",
                 "medals": ["gold", "silver", "bronze"]}