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、不能将不定参传递给另一个不定参