Go 基础

Go 简介

  • 1、2007年,由 Google 公司的软件工程师创造,准备用来取代 C++,并于2009年正式对外发布。
  • 2、Go 语言语法相对简单,比较容易上手;
  • 3、Go拥有接近C的运行效率和接近PHP的开发效率。
  • 4、Go 是一种非常高效的语言,高度支持并发性。
  • 5、拥有 GC (垃圾收集器)的机制,对变量进行跟踪,并且在不需要时自动释放他们;
  • 6、为多核计算机提供性能提升方案;
  • 7、UTF-8编码支持;

基本语法

// 当前程序的包名
// 只有 package 名称为 main 的包可以包含 main 函数
// 一个可执行的程序有且只有一个 main 包
package main 
// 导入其他包
import "fmt" 
import "container/list"
// 定义常量
const PI = 3.14
// 定义全局变量
var num int = 4
// 定义方法
func test() {
   // 简略写法,此种方法只能写在方体里面
   tmp := "test" + "123"
   fmt.Println(tmp)
}
// 指针的使用
func test_ptr() {
   tmp := "yangzw"
   // 获取变量取地址后的指针值
   fmt.Println(&tmp)
   // 通过指针取值
   // 取地址操作符 & 和取值操作符 * 是一对互补操作符,& 取出地址,* 根据地址取出地址指向的值。
   ptr := &tmp
   fmt.Println(*ptr)
   // swap 方法只交换 a、b 变量的地址,但是指针和值的关联并没有交换,一次结果不会交换两个变量
   // 使用 swap_tmp 方法才可以交换两值
   // 就像两张写有不同名字的纸片,交换纸片后对应的名字是不变的
   x, y := 1, 2
   swap(&x, &y)
   fmt.Println(x, y)
   // 输出结果:1 2
}
func swap(a, b *int) {
   b, a = a, b
}
func swap_tmp(a, b *int) {
   t := *a
   *a = *b
   *b = t
}
func main() {
   test()
   test_ptr()

   /*
    * 荣天气的使用
    */
   // 1、数组使用
   var a [8]int = [8]int{1, 2, 3, 4, 5, 6}
   for i, v := range a {
      fmt.Println(i, v)
   }
   // 2、切片使用
   fmt.Println(a, a[1:2])
   // 输出结果:[1 2 3] [2]

   fmt.Println(a, a[:2])
   fmt.Println(a, a[4:])
   fmt.Println(a, a[:])   // 原有切片
   fmt.Println(a, a[0:0]) // 清空切片

   // 从数组或切片生成新的切片拥有如下特性:
   // 取出的元素数量为:结束位置-开始位置。
   // 取出元素不包含结束位置对应的索引,切片最后一个元素使用 slice[len(slice)] 获取。
   // 当缺省开始位置时,表示从连续区域开头到结束位置。
   // 当缺省结束位置时,表示从开始位置到整个连续区域末尾。
   // 两者同时缺省时,与切片本身等效。
   // 两者同时为0时,等效于空切片,一般用于切片复位

   // 使用 make 函数构造切片
   // 10 代表分配空间,并不会影响长度
   b := make([]int, 2, 10)
   fmt.Println(b)
   // 输出结构:[0 0]

   // 向切片中添加元素
   var slice []int
   slice.append(slice, 7, 8)
   fmt.Println(slice)
   // 复制切片 copy(slice1, slice2) 将 slice2 中元素复制到 slice1 中

   // 3、map 使用
   var map1 = map[string]int{"one": 1, "two": 2}
   map2 := make(map[string]int)
   map2["three"] = 3
   delete(map1, "one") // 删除 map 中的元素

   // 4、列表使用
   l1 := list.New()
   // var l2 list.list
   tmp := l1.PushBack("fist") // 尾部添加元素
   l1.PushFront(67)    // 头部添加元素
   l1.InsertAfter("high", tmp) // 在 first 后插入 high
   l1.InsertBefore("noon", tmp)
   l1.Remove(tmp) // 移除元素
   // 遍历获取 list 元素
   // 其中 i:=l.Front() 表示初始赋值,只会在一开始执行一次;每次循环会进行一次 i!=nil 语句判断,如果返回 false,表示退出循环,反之则会执行 i=i.Next()
   for i := l1.Front(); i != nil; i = i.Next() {
      fmt.Println(i.Value)
  }
}

函数使用

  • 1、基本使用
// 普通函数
func demo1() {
    fmt.Println("普通函数")
}
// 带参数函数
func demo2(i int, str string) {
    fmt.Println(i, str)
}
// 带参数和返回值函数
func demo3(i, j int) int {
    return i + j
}
// 多个返回值函数
func demo4(i, j int) (int, int) {
    return i, j
}
  • 2、函数类型
// 可变参数类型
func demo1(str string, nums ...int) {
    for _, val := range nums {
        fmt.Println(str, val)
    }
}
// 当无法取人传入参数类型时,可以使用默认的空接口 interface{},这样就可以接收任意类型的参数
func demo2(value ...interface{}) {
    for _, val := range value {
        switch val.(type) {
        case int:
            fmt.Println("int")
        case string:
            fmt.Println("string")
        case bool:
            fmt.Println("bool")
        default:
            fmt.Println("unknow")
        } 
    }
}
/*
 * 将函数当作一个参数进行传递
 */
// 声明一个函数类型
type demo3 func(int) bool
func demo4(i int) bool {
    if i % 2 == 0 {
        return true
    }
    return false
}
func demo5(nums []int, f demo3) {
    for _, num := range nums {
        if f(num) {
            fmt.Println(num, "是偶数")
        } else {
            fmt.Println(num, "是奇数")
        }
    }
}

结构体

结构体知识一种内存布局描述,只有实例化后才会正式分配内存

// 定义一个结构体
type animal struct {
    name string
    age int
}
// 添加结构体方法
func (a *animal) setName(name string) {
    a.name = name
}
type Cat struct {
    Color string
    Name  string
}

func NewCatByName(name string) *Cat {
    return &Cat{
        Name: name,
    }
}

func main() {
    // 实例化结构体方式
    // 1、普通初始化
    var an animal
    // 2、通过 new 实例化结构体 此时形成的是指针类型的结构体
    b := new(animal)
    // 初始化结构体变量
    c := &animal {
        name: "dog",
        age: 12,
    }
    d := animal {
        "dog",
        12,
    }
    b.setName("dd")
}

注意事项

  • 1、变量声明必须使用,同一个 {} 内声明的变量是唯一的;
  • 2、数据交换
i, j := 1,2
i,j = j, i
  • 3、单引号表示字符,双引号表示字符串
  • 4、接收键盘收入
var a int
fmt.Scan(&a)
  • 5、类型转换只能在相互兼容的类型间进行转换
  • 6、不能将不定参传递给另一个不定参

推荐阅读更多精彩内容

  • 运算符 算数运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符ps:为防止发生混淆,go语法规定,+...
    名字刚好七个字阅读 71评论 1 0
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 5,356评论 0 38
  • 安装和环境配置 自行百度解决 go项目的目录结构 go命令依赖一个重要的环境变量:$GOPATH一般的,一个Go项...
    名字刚好七个字阅读 44评论 0 0
  • Go基础 Go与c对比 Go中的注释与C的注释一样,有多行和单行,细节都一样 都是由函数组成的 入口函数都是mai...
    无尾树袋熊阅读 25评论 0 0
  • 运行 hello world 报错 go run test.go go run: cannot run non-m...
    Edmond_33阅读 99评论 0 0