您的位置:首页 > 编程语言 > Go语言

Go语言学习笔记(二)十分钟上手

2017-07-14 10:02 288 查看
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959

变量&常量

变量

  变量名由字母、数字、下划线组成,不能以数字开头。

...
var (
A int    //默认为0
B string //默认为""
C bool   //默认为false

Name string = "suoning"
Age         = 18 // 自动识别类型
)

func main() {
sex := "man"          //等价于 var sex string = "man"
var girlfriend string //声明变量
girlfriend = "Dawn"   //变量赋值

Name := "Nick" //正确
//girlfriend := "Jenny"    //错误的!不能申明两次
...
}


常量

常量使用const 修饰,代表永远是只读的,不能修改。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

语法:const identifier [type] = value,其中type可以省略。

iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。

...
const (
A = 'a'    //97
B = iota   //1
C          //2
D = "nick" //"nick"  iota += 1
E          //"nick"  iota += 1
F = 618    //618  iota +=1
G          //618  iota +=1
H = iota   //7
I          //8
)
...


基本数据类型

布尔型

布尔型的值只可以是常量 true 或者 false。

var a bool
var a bool = true
var a = false


数字类型

int:

uint8(无符号 8 位整型 (0 到 255))

uint16(无符号 16 位整型 (0 到 65535))

uint32(无符号 32 位整型 (0 到 4294967295))

uint64(无符号 64 位整型 (0 到 18446744073709551615))

int8(有符号 8 位整型 (-128 到 127))

int16(有符号 16 位整型 (-32768 到 32767))

int32(有符号 32 位整型 (-2147483648 到 2147483647))

int64(有符号 64 位整型 (-9223372036854775808 到 9223372036854775807))

float:

float32(IEEE-754 32位浮点型数)

float64(IEEE-754 64位浮点型数)

complex64(32 位实数和虚数)

complex128(64 位实数和虚数)

其它:

byte(类似 uint8)

rune(类似 int32)

uint(32 或 64 位)

int(与 uint 一样大小)

uintptr(无符号整型,用于存放一个指针)

类型转换

package main

func main() {
var a int
var b int32
var c int64
a = 15
//b = a + a // compiler error
b = int32(a + a) // ok
b = b + 5 // ok: 5 is a constant
c = c + 5 // ok
}


字符类型

存储为ascii码

var a byte = 'a'
fmt.Println(a)    //97


字符串类型

字符串表示两种方式:

双引号

`` (反引号,不转义)

string底层就是一个byte的数组

string本身是不可变的,因此要改变string中字符,需要如下操作:

str := "hello world"
s := []byte(str)
s[0] = 'o'
str = string(s)


操作符

算术运算符

+ 相加

- 相减

* 相乘

/ 相除

% 求余

++ 自增

-- 自减

关系运算符

== 检查两个值是否相等,如果相等返回 True 否则返回 False。

!= 检查两个值是否不相等,如果不相等返回 True 否则返回 False。

> 检查左边值是否大于右边值,如果是返回 True 否则返回 False。

< 检查左边值是否小于右边值,如果是返回 True 否则返回 False。

>= 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。

<= 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。

逻辑运算符

&& 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。

|| 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。

! 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。

位运算符

位运算符对整数在内存中的二进制位进行操作。

& 按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。

| 按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或。

^ 按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。

<< 左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。

>> 右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。

赋值运算符

= 简单的赋值运算符,将一个表达式的值赋给一个左值

+= 相加后再赋值 (C += A 等于 C = C + A)

-= 相减后再赋值 (C -= A 等于 C = C - A)

*= 相乘后再赋值 (C *= A 等于 C = C * A)

/= 相除后再赋值 (C /= A 等于 C = C / A)

%= 求余后再赋值 (C %= A 等于 C = C % A)

<<= 左移后赋值 (C <<= 2 等于 C = C << 2)

>>= 右移后赋值 (C >>= 2 等于 C = C >> 2)

&= 按位与后赋值 (C &= 2 等于 C = C & 2)

^= 按位异或后赋值 (C ^= 2 等于 C = C ^ 2)

|= 按位或后赋值 (C |= 2 等于 C = C | 2)

流程控制

If/else & for & range

注意 else if / else 位置

if condition1 {
} else if condition2 {
} else if condition3 {

} else {
}


for循环条件没有小括号

for i := 0; i < 10; i++ {
}


死循环

for true {
}
可以简写为:
for {
}


range

for i, v := range str {
}


package main

import (
"fmt"
"strings"
)

func makeSuffix(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}

func main() {
f1 := makeSuffix(".png")
fmt.Println(f1("name1"))    //name1.png
fmt.Println(f1("name2"))    //name2.png

f2 := makeSuffix(".jpg")
fmt.Println(f2("name1"))    //name1.jpg
fmt.Println(f2("name2"))    //name2.jpg
}


闭包栗子二

值传递 & 引用传递

无论是值传递,还是引用传递,传递给函数的都是变量的副本;

值传递是值的拷贝,引用传递是地址的拷贝;

一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。

map、slice、chan、指针、interface默认以引用的方式传递。

new 内置函数 用来分配内存,主要用来分配值类型,比如int、struct,返回的是指针;

make 内置函数 用来分配内存,主要用来分配引用类型,比如chan、map、slice。

程序初始化与执行过程

程序的初始化和执行都起始于main包。
如果main包还导入了其它的包,那么就会在编译时将它们依次导入。
有时一个包会被多个包同时导入,那么它只会被导入一次(例如很多包可能都会用到fmt包,但它只会被导入一次,因为没有必要导入多次)。
当一个包被导入时,如果该包还导入了其它的包,那么会先将其它包导入进来,然后再对这些包中的包级常量和变量进行初始化,接着执行init函数(如果有的话),依次类推。
等所有被导入的包都加载完毕了,就会开始对main包中的包级常量和变量进行初始化,然后执行main包中的init函数(如果存在的话),最后执行main函数。



指针类型(&*)

普通类型,变量存的就是值,也叫值类型;

指针类型,变量存的是一个地址,这个地址存的才是值。

变量是一种占位符,用于引用计算机内存地址;

Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

获取指针类型所指向的值,使用:*。

一个指针变量可以指向任何一个值的内存地址它指向那个值的内存地址。

申明如下:

var age *int           //指向整型
var height *float32    //指向浮点型


当一个指针被定义后没有分配到任何变量时,它的值为 nil。

nil 指针也称为空指针。

栗子

package main

import "fmt"

func main() {
var ptr *int
num := 100
ptr = &num
fmt.Println(ptr)    //0xc42000e1f8
fmt.Println(*ptr)   //100
*ptr = 200
fmt.Println(num)    //200
}


package main

import "fmt"

func change(num *int) {
fmt.Println(num)    //0xc42000e1f8
fmt.Println(*num)   //100
*num = 1000
fmt.Println(num)    //0xc42000e1f8
fmt.Println(*num)   //1000
}

func main() {
num := 100
fmt.Println(&num)    //0xc42000e1f8
change(&num)
fmt.Println(&num)    //0xc42000e1f8
fmt.Println(num)     //1000
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: