Go 入门笔记
Posted engchina
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go 入门笔记相关的知识,希望对你有一定的参考价值。
Go 入门笔记
指针
指针是一种特殊类型,它的实例讲保存被引用对象的内存地址,而不是对象自身的值。
指针变量在声明后如果未获得有效的内存地址,那么它的默认值就是nil(空引用)。
示例代码,
package main
import "fmt"
func main()
var p1 *bool
fmt.Println("p1 的默认值:", p1)
var p2 *int8
fmt.Println("p2 的默认值:", p2)
var p3 *string
fmt.Println("p3 的默认值:", p3)
输出结果,
p1 的默认值: <nil>
p2 的默认值: <nil>
p3 的默认值: <nil>
在类型名称前面加上"*"(星号)运算符,就是对应的指针类型。
在变量名称前面加上"&"运算符,就能获得该变量值的内存地址。其运算结果为指向该变量类型的指针。
示例代码,
package main
import "fmt"
func main()
var k = "abcdefg"
var pk = &k
fmt.Println("k 的内存地址是:", pk)
输出结果,
k 的内存地址是: 0xc00008a260
new 函数
new 函数为指定的类型分配内存空间,并使用类型的默认值进行初始化,最后返回新分配内存空间的地址。
new 函数的定义如下,
func new(Type) *Type
代码示例,
package main
import "fmt"
func main()
var px *int16 = new(int16)
fmt.Printf("px 指向的内存地址: %p\\n", px)
fmt.Printf("px 所指向对象的值: %v\\n", *px)
输出结果,
px 指向的内存地址: 0xc00001c0c8
px 所指向对象的值: 0
以下几点需要注意,
-
new(String) 所分配的值并不是 nil,而是空字符串(“”)。
-
结构体分配内存空间后,会为其字段分配默认值。
-
接口类型使用 new 函数分配内存空间后,其默认值为 nil(空指针)。
代码示例,
package main
import "fmt"
func main()
type sender interface
LineOut(data []byte) int
var pi = new(sender)
fmt.Println(*pi)
输出结果,
<nil>
iota 常量
iota 常量的定义如下,
const iota = 0
这是一个有特殊用途的常量,在批量定义常量的代码中(这些代码一般写在小括号中),如果常量 A 使用了 iota 常量作为基础整数值,那么在 A 之后定义的常量会自动累加。
代码示例,
package main
import "fmt"
const (
A = iota
B
C
D
)
func main()
fmt.Println("A:", A)
fmt.Println("B:", B)
fmt.Println("C:", C)
fmt.Println("D:", D)
输出结果,
D:\\Users\\thinkpad\\AppData\\Local\\Temp\\GoLand\\___go_build_99_Learn.exe
A: 0
B: 1
C: 2
D: 3
当 iota 出现在常量列表的首位置时,它的值为 0,但随着出现的位置不同,iota 常量的值也会改变。
以下述代码为例,当定义 W 常量时,iota 的值为 4(第五个变量,从 0 开始计算),iota + 3 使得 W 的值为 7。
package main
import "fmt"
const (
S = 17
T = 9
U = iota
V = iota
W = iota + 3
X = iota + 3
Y = iota + 3
Z = iota + 3
)
func main()
fmt.Println("S:", S)
fmt.Println("T:", T)
fmt.Println("U:", U)
fmt.Println("V:", V)
fmt.Println("W:", W)
fmt.Println("X:", X)
fmt.Println("Y:", Y)
fmt.Println("Z:", Z)
输出结果,
S: 17
T: 9
U: 2
V: 3
W: 7
X: 8
Y: 9
Z: 10
未完待续!
Go入门笔记
《Go程序设计语言》作者Kerninghan教授与谷歌GO开发团队核心成员联合编写,Go语言编程圣经。本笔记是学习翻阅此书中文翻译版,整理而成。 非常感谢李道兵、 高博等辛苦的翻译。
Go IDE-Golang 使用入门参考如下。
https://www.2cto.com/kf/201704/632395.html
Go语言简介
【1】Go语言是编译型语言。Go 的工具链将程序的源文件转变成机器相关的二进制指令。Go代码是使用包来组织的,包类似于其他语言的模块。一个包由一个或者多个go文件组成,放在同一个文件夹中,文件夹的名字描述了包的作用。每一个源文件的开始都使用package声明,指明了这个文件属于哪个包。
【2】import 必须在package声明后面,import导入声明后面是组成程序的函数、变量、常量、类型(func、var、const、type)开头声明。大部分情况下声明的顺序是没有关系的。
【3】Go不需要在语句或者声明后面使用分号结尾,除非有多个语句或者声明出现在同一行。Go代码格式化要求非常严格。
【4】Go不允许存在无用的变量或者无用的包导入,不然会出现编译错误。如果有些变量返回必须需要变量占位,可以使用空标识符”_”。空标识符可以用在任何语法需要变量名但是程序逻辑不需要的地方,例如丢掉每次迭代产生的无用的索引。
【5】“:=”是Go语言中特有的短变量声明和初始化,更加简洁,但是通常在一个函数的内部使用,不适合包级别的变量。
// = 使用必须使用先var声明例如:
var a
a=100
//或
var b = 100
//或
var c int = 100
// := 是声明并赋值,并且系统自动推断类型,不需要var关键字
d := 100
进程 线程 协程
进程:独立的栈空间,独立的堆空间,进程之间调度由os完成。
线程:独立的栈空间,共享堆空间,内核线程之间调度由os完成。
协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
goroutine-channel-select
参考链接:http://blog.csdn.net/qwertyupoiuytr/article/details/55101258
goroutine:原生支持语言级并发,这个并发的最小逻辑单元就是goroutine。goroutine就是Go语言提供的一种用户态线程,这种用户态线程是跑在内核级线程之上的,goroutine在运行时的调度是由Go语言提供的调度器来进行的,创建一个goroutine使用关键字go,go创建的goroutine不会阻塞主线程:
go func_name()
channel:Channel是Go中的一个核心类型,可以把它看成一个管道,通过它可以发送或者接收数据进行通讯(communication)。配合goroutine,形成了一种既简单又强大的请求处理模型。
channel的基本操作:
var c chan int //声明一个int类型的channel,注意,该语句仅声明,不初始化channel
c := make(chan type_name) //创建一个无缓冲的type_name型的channel,无缓冲的channel当放入1个元素后,后续的输入便会阻塞
c := make(chan type_name, 100) //创建一个缓冲区大小为100的type_name型的channel
c <- x //将x发送到channel c中,如果channel缓冲区满,则阻塞当前goroutine
<- c //从channel c中接收一个值,如果缓冲区为空,则阻塞
x = <- c //从channel c中接收一个值并存到x中,如果缓冲区为空,则阻塞
x, ok = <- c //从channel c中接收一个值,如果channel关闭了,那么ok为false(在没有defaultselect语句的前提下),在channel未关闭且为空的情况下,仍然阻塞
close(c) //关闭channel c
for term := range c //等待并取出channelc中的值,直到channel关闭,会阻塞
单向channel:
var ch1 chan<- float64 //只能向里面写入float64的数据,不能读取
var ch2 <-chan int //只能读取int型数据
select:select用于在多个channel上同时进行侦听并收发消息,当任何一个case满足条件时即执行,如果没有可执行的case则会执行default的case,如果没有指定defaultcase,则会阻塞程序,select的语法:
func TestChannel()
// For our example we'll select across two channels.
c1 := make(chan string)
c2 := make(chan string)
// Each channel will receive a value after some amount
// of time, to simulate e.g. blocking RPC operations
// executing in concurrent goroutines.
go func()
time.Sleep(time.Second * 1)
c1 <- "one"
()
go func()
time.Sleep(time.Second * 2)
c2 <- "two"
()
// We'll use `select` to await both of these values
// simultaneously, printing each one as it arrives.
for i := 0; i < 2; i++
select
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
Go Web简单例子
package server
import (
"net/http"
"fmt"
"log"
"ch01/lissajous"
)
func Server1()
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe("localhost:8000", nil))
func handler(w http.ResponseWriter,r *http.Request)
fmt.Fprintf(w,"URL.PATH = %q\\n",r.URL.Path)
lissajous.Lissajous(w)
以上是关于Go 入门笔记的主要内容,如果未能解决你的问题,请参考以下文章