Golang学习笔记

特点

Go 语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率动态语言开发维护的高效率

使用一个表达式来形容 Go 语言:Go = C + Python

说明 Go 语言既有 C 静态语言程序的运行速度,又能达到 Python 动态语言的快速开发

天然并发

  1. 从语言层面支持并发,实现简单
  2. goroutine,轻量级线程,可实现大并发处理,高效利用多核
  3. 基于 CSP 并发模型(Communicating Sequential Processes)实现

函数可以返回多个值

func getSumAndSub(n1 int, n2 int) (int, int ) {
   
	sum := n1 + n2
	sub := n1 - n2
	return sum , sub
}

开发目录结构

在这里插入图片描述

Golang 执行流程分析

如果是对源码编译后,再执行,Go 的执行流程如下图
在这里插入图片描述
如果我们是对源码直接 执行 go run 源码,Go 的执行流程如下图
在这里插入图片描述
两种执行流程的方式区别:

  1. 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有 go 开发环境的机器上,仍然可以运行
  2. 如果我们是直接 go rungo 源代码,那么如果要在另外一个机器上这么运行,也需要 go 开发环境,否则无法执行
  3. 在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了很多

基础

导入

使用

import (
	"fmt"
	"math"
)

代替

import "fmt"
import "math"

以简化导入

函数

使用

x, y int

代替

x int, y int

以简化声明

多值返回

函数可以返回任意数量的返回值。

package main

import "fmt"

func swap(x, y string) (string, string) {
   
	return y, x
}

func main() {
   
	a, b := swap("hello", "world")
	fmt.Println(a, b)
}
world hello

若直接return则按变量声明顺序返回

短变量声明

在函数中,简洁赋值语句 := 可在类型明确的地方代替 var 声明。

函数外的每个语句都必须以关键字开始(var, func 等等),因此 := 结构不能在函数外使用。

package main

import "fmt"

func main() {
   
	var i, j int = 1, 2
	k := 3
	c, python, java := true, false, "no!"

	fmt.Println(i, j, k, c, python, java)
}
1 2 3 true false no!

常量

常量的声明与变量类似,只不过是使用 const 关键字。

常量可以是字符、字符串、布尔值或数值。

常量不能用 := 语法声明。

package main

import "fmt"

const Pi = 3.14

func main() {
   
	const World = "世界"
	fmt.Println("Hello", World)
	fmt.Println("Happy", Pi, "Day")

	const Truth = true
	fmt.Println("Go rules?", Truth)
}

for

package main

import "fmt"

func main() {
   
	sum := 0
	for i := 0; i < 10; i++ {
   
		sum += i
	}
	fmt.Println(sum)
}
45

初始化语句和后置语句是可选的,for 是 Go 中的 “while”

package main

import "fmt"

func main() {
   
	sum := 1
	for sum < 1000 {
   
		sum += sum
	}
	fmt.Println(sum)
}
1024

如果省略循环条件,该循环就不会结束,因此无限循环可以写得很紧凑。

package main

func main() {
   
	for {
   
	}
}

if 的简短语句

同 for 一样, if 语句可以在条件表达式前执行一个简单的语句。

该语句声明的变量作用域仅在 if 之内。

package main

import (
	"fmt"
	"math"
)

func pow(x, n, lim float64) float64 {
   
	if v := math.Pow(x, n); v < lim {
   
		return v
	}
	return lim
}

func main() {
   
	fmt.Println(
		pow(3, 2, 10),
		pow(3, 3, 20),
	)
}
9 20

switch

switch 是编写一连串 if - else 语句的简便方法。它运行第一个值等于条件表达式的 case 语句。

Go 的 switch 语句类似于 C、C++、Java、JavaScript 和 PHP 中的,不过 Go 只运行选定的 case,而非之后所有的 case。

实际上,Go 自动提供了在这些语言中每个 case 后面所需的 break 语句。 除非以 fallthrough 语句结束,否则分支会自动终止。

Go 的另一点重要的不同在于 switch 的 case 无需为常量,且取值不必为整数。

package main

import (
	"fmt"
	"runtime"
)

func main() {
   
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os {
   
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("%s.\n", os)
	}
}

输出根据运行代码机器的os决定

defer

defer 语句会将函数推迟到外层函数返回之后执行。

推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。

package main

import "fmt"

func main() {
   
	defer fmt.Println("world")

	fmt.Println("hello")
}
hello
world

推迟的函数调用会被压入一个栈中。

当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

package main

import "fmt"

func main() {
   
	fmt.Println("counting")

	for i := 0; i < 10; i++ {
   
		defer fmt.Println(i)
	}

	fmt.Println("done")
}
counting
done
9
8
7
6
5
4
3
2
1
0

指针

Go 拥有指针。指针保存了值的内存地址。

类型 *T 是指向 T 类型值的指针。其零值为 nil

var p *int

& 操作符会生成一个指向其操作数的指针。

i := 42
p = &i

* 操作符表示指针指向的底层值。

fmt.Println(*p) // 通过指针 p 读取 i
*p = 21         // 通过指针 p 设置 i

这也就是通常所说的“间接引用”或“重定向”。

与 C 不同,Go 没有指针运算。

package main

import "fmt"

func main() {
   
	i, j := 42, 2701

	p := &i         // 指向 i
	fmt.Println
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值