Golang 学习总结(1) - 关键字

skygrey · · 133 次点击 · · 开始浏览    

前言

最近看完了两本golang的书,也使用golang搭建了一个框架,写了一个物联网项目
所以来做个入门总结

关键字

golang 一共有25个关键字 ,不能用作标识符,分成三大类,程序包管理、实体声明和定义、流程控制
如果有其它语言基础,大部分都可以知道其功能

程序包管理:

package

package用于声明包的名称,需放在go文件所有代码的最前面。一个包由一个或多个go源文件组成,需放在同一个目录下,且同一个目录下的这些go文件的package的名字只能有一个

import 包引入

其中包路径前面可以有三中修饰符中的某一个 [ _ . alias ]

package <packagename>
import _ "package path"
import . "package path"
import alias "package path"

import (
    _ "package path"
    . "package path"
    alias "package path"
)

实体声明和定义

var

定义变量

var name T          //name默认为类型T的零值
var name = value    //根据值value推断变量name的类型
var name T = value  //赋初始值时指明类型
var name1, name2 T  //同时定义多个同类型变量
//同时定义多个不同类型的变量
var (
    name string ="dable"
    age int = 18
)
//最简单用法,也是最常用法
name := value

const 常量

同 var

func 函数和方法

func 用于定义函数,Go函数支持变参且返回值支持多个。

func funcName(){}                           //无参无返回值
func funcName(t T) T {}                     //有参有返回值
func funcName(t T, list ...T) (T1,T1) {}    //有变参有多个返回值
func (s struct) funcName() {}  //可以带结构体

type 类型

type 用于定义类型,比如定义struct、interface等类型

struct 结构体

struct 用于定义结构体

type Name struct {
    X, Y int
}

interface 接口

interface 用于定义接口。一个接口是一个方法集,如果一个类型实现了一个接口中的所有方法集,那么说明该类型实现此接口。接口类型变量可以存储任何实现了该接口的类型的值。特别的,interface{}表示空接口类型,默认地,所有类型均实现了空接口,所以interface{}可以接收任意类型值。

//空接口
interface{}
//Person接口
type Person interface {
        Walk()
    Run() 
    Say(s string)
}

map 字典

map 用于声明映射变量。映射属容器类类型,是一个同种类型元素的无序组,通过唯一的键可以获取对应的值。可以使用 make 创建 map 变量,未初始化的映射值为 nil。创建map变量主要有如下几种方式:

//创建0容量的map
var map1 = make(map[T1] T2) 

//创建指定容量的map,只是初始容量,会自动扩容
var map2 = make(map[T]T2, 10) 

//创建并初始化map
var map3 = map[string]int { 
    "k1" : 1,
    "k2" : 2,
} 
// 创建可以放任意值的map
var map4 = make(map[string]interface{})

chan 管道

chan用于声明channel(信道)。信道提供一种机制使两个并发执行的函数实现同步,并通过传递具体元素类型的值来通信。未初始化的信道值为 nil。声明格式如下:


//定义chan类型变量
var ch chan int = make(chan int, 10);
//或者
ch := make(chan int, 10);
 
//给chan写数据 
ch <- 1;
ch <- 2;
 
//从chan 读数据
var x int;
x = <-ch;

其中<-操作符指定信道的方向,发送或接收。若没有给定方向,那么该信道就是双向的。信道可通过类型转换或赋值被强制为只发送或只接收。
信道的初始化可以通过 make 函数来实现,其结果值充当了对底层数据结构的引用。初始化时可以为信道设置缓冲区大小,默认值是零,表示不带缓冲的或同步的信道

ci := make(chan int)            // 整数类型的无缓冲信道
cj := make(chan int, 0)         // 整数类型的无缓冲信道
cp := make(chan *os.File, 100)  // 指向文件指针的带缓冲信道

流程控制

go 多线程

go用于创建Go线程(goroutine),实现并发编程。Go程是与其它Go程并发运行在同一地址空间的函数,相比于线程与进程,它是轻量级的。Go程在多线程操作系统上可实现多路复用,因此若一个线程阻塞,比如说等待I/O,那么其它的线程就会运行。Go程的设计隐藏了线程创建和管理的诸多复杂性。

在函数或方法前添加 go 关键字能够在新的Go程中调用它。当调用完成后,该Go程也会安静地退出。效果有点像Unix Shell中的 & 符号,它能让命令在后台运行。

//并发执行
go func()

select

select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行
Go 编程语言中 select 语句的语法如下:

select {
    case communication clause  :
       statement(s);      
    case communication clause  :
       statement(s);
    /* 你可以定义任意数量的 case */
    default : /* 可选 */
       statement(s);
}

for 循环

for是Go中唯一用于循环结构的关键词。有三个使用方式,分别是单个循环条件,经典的初始化/条件/后续形式,还有和range关键词结合使用来遍历容器类对象(数组、切片、映射)。

//单条件
i := 1
for i <= 3 {
    fmt.Println(i)
    i = i + 1
}

//初始化/条件/后续形式
//注意Go中没有前置自增与自减运算符,即++i是非法的
for i:=0; i < 3; i++ {
    fmt.Println(i)
}

//for range形式遍历数组
array :=[...]int{0,1,2,3,4,5}
for i, v :=range array{
    fmt.Println(i,v)
}

range 迭代器

同 for 一起使用,遍历对象↑

break

break用于终止最内层的"for"、“switch"或"select"语句的执行。

continue

结合for一起使用,continue通常用于结束当前循环

if else

条件判断语句

  • 可省略条件表达式的括号;
  • 支持初始化语句,可定义代码块局部变量;
  • if与else块中只有一条语句也需要添加大括号;
  • 起始大括号必须与if与else同行。
if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
} else{
  /* 在布尔表达式为 false 时执行 */
}

//支持多个else if
if 表达式1 {
  // 符合表达式1执行
} else if 表达式2 {
  // 符合表达式2 执行
} else {
  // 没有符合的表达式执行
}

// 可以声明变量 
if bool := true;bool {
  //执行
}

switch case default fallthrough

这四个关键字是结合使用的,switch语句提供多路执行,表达式或类型说明符与switch中的case相比较从而决定执行哪一分支。default用于给出默认分支,即所有的case分支都不满足时执行default分支。Go中的switch语句在执行完某个case子句后,不会再顺序地执行后面的case子句,而是结束当前switch语句。使用fallthrough可以继续执行后面的case与default子句。

//表达式选择

switch tag {
default: s3()           //default子句可以出现在switch语句中的任意位置,不一定是最后一个
case 0, 1, 2, 3: s1()   //case表达式可以提供多个待匹配的值,使用逗号分隔
case 4, 5, 6, 7: s2()
}

switch x := f(); {      
case x < 0: return -x   //case表达式无需为常量
default: return x
}

switch {                //缺失的switch表达式意为"true"
case x < y: f1()
fallthrough             //强制执行下一个case子句
case x < z: f2()
//此处没有fallthrough,switch执行流在此终止 
case x == 4: f3()
}

//类型选择
switch i := x.(type) {
case int:
    printInt(i)                            // i 的类型为 int
case float64:
    printFloat64(i)                        // i 的类型为 float64
case func(int) float64:
    printFunction(i)                       // i 的类型为 func(int) float64
case bool, string:
    printString("type is bool or string")  // i 的类型为 bool or string
default:
    printString("don't know the type")     // i 的类型未知
}

defer

defer语句用于预设一个函数调用,即推迟函数的执行。 该函数会在执行 defer 的函数返回之前立即执行。它显得非比寻常, 但却是处理一些事情的有效方式,例如无论以何种路径返回,都必须释放资源的函数。 典型的例子就是解锁互斥和关闭文件。如果有多个defer 按照倒序执行。

//将文件的内容作为字符串返回。
func Contents(filename string) (string, error) {
    f, err := os.Open(filename)
    if err != nil {
        return "", err
    }
    defer f.Close()  // f.Close 会在函数结束后运行

    var result []byte
    buf := make([]byte, 100)
    for {
        n, err := f.Read(buf[0:])
        result = append(result, buf[0:n]...)
        if err != nil {
            if err == io.EOF {
                break
            }
            return "", err  // 我们在这里返回后,f 就会被关闭
        }
    }
    return string(result), nil // 我们在这里返回后,f 就会被关闭
}

goto

goto用于将程序的执行转移到与其标签相应的语句。可以使用goto退出多层"for"、“switch"或"select”,功能类似于break携带标签。

//终止for
L:
    for i < n {
      n++
      goto L
    }

return

return用于函数执行的终止并可选地提供一个或多个返回值。 任何在函数F中被推迟的函数会在F 返回给其调用者前执行。函数可以通过return返回多个值。如果返回值在函数返回形参中指定了名字,那么return时可不带返回值列表。

//无返回值
func noResult() {
    return
}

//单返回值
func f1() int {
    return 2
}

//多返回值
func f2() (float64, float64) {
    re = 7.0
    im = 4.0
    return re, im
}

//返回值已具名
unc f3() (re float64, im float64) {
    re = 7.0
    im = 4.0
    return
}

原文:http://www.idmiss.com/?p=663

参考:


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:skygrey

查看原文:Golang 学习总结(1) - 关键字

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

133 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传