go理论及工程

工程

  1. 官网下载安装goland
  2. 打开一个go项目之后,在terminal下执行安装依赖项
  • 注意export是Linux/Mac OS中的命令,Windows中应使用如下例所示
$env:GO111MODULE = "on"

参考解决
3. 添加service.go配置文件
4. run goland代码,出现***.log即run成功。前三步没问题不能run时可重启(reload disk)。

理论

变量

变量可以通过变量名访问。Go语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。声明变量的一般形式是使用var关键字:

var identifier type

可以一次声明多个变量:

var identifier1, identifier2 type

变量声明

  1. 指定变量类型,如果没有初始化则变量默认为零值。
var v_name v_type
v_name = value
  • 数值类型(包括complex64/128)为0
  • 布尔类型为false
  • 字符串为""(空字符串)
  • 以下几种类型为nil:
var a *int
var a []int
var a map[string] int
var a chan int
var a func(string) int
var a error // error 是接口
  1. 根据值自行判定变量类型
var v_name = value
  1. 如果变量已经使用var声明过了,再使用 := 声明变量,就产生编译错误,格式:
v_name := value

多变量声明

//类型相同多个变量,非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 //不需要显示声明类型,自动推断
vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该是已经被声明             
                                       过的,否则会导致编译错误
// 这种因式分解关键字的写法一般用于声明全局变量
var (
	vname1 v_type1
	vname2 v_type2
)

数据

  1. array
  • 数组是值类型,赋值和传参会复制整个数组,而不是指针。
  • 数组畅度必须是常量,且是类型的组成部分。[2]int和[3]int是不同类型。
  • 支持’‘==’‘、’‘!=’'操作符,因为内存总是被初始化过的。
  • 指针数组[n]*T, 数组指针 *[n]T。
    可用复合语句初始化。
a := [3]int{
   
   1,2}            //未初始化元素值为0。
b := [...]int{
   
   1,2,3,4}      //通过初始化值确定数组长度。
c := [5]int{
   
   2: 100, 4:100}  //通过索引号初始化元素。

d := [...]struct{
   
   
	name string
	age uint8
}{
   
   
	{
   
   "user1", 10},         //可省略元素类型。
	{
   
   "user2", 20},         //别忘了最后一行的逗号,
}

支持多维数组。

a := [2][3]int{
   
   {
   
   1,2,3}, {
   
   4,5,6}}
b := [...][2]int{
   
   {
   
   1,1}, {
   
   2,2}, {
   
   3,3}}  //第2纬度不能用"..."

值拷贝行为会造成性能问题,通常会建议使用slice,或数组指针。

func test(x [2]int){
   
   
	fmt.Printf("x: %p\n", &a)
	test(a)
	fmt.Println(a)
}

输出:

a: 0x2101f9150
x: 0x2101f9170
[0,0]

内置函数len和cap都返回数组长度(元素数量)。

a := [2]int{
   
   }
println(len(a), cap(a))    //2, 2

Slice

slice并不是数组或数组指针。它通过内部指针和相关属性引用数组片段,以实现变长方案。
runtime.h

struct Slice
{
   
                             //must not move anything
	byte*  array;          //actual data
	uintgo len;            //number of elements
	uintgo cap;            //allocated number of elements	
}
  • 引用类型。但自身是结构体,值拷贝传递。
  • 属性len表示可用元素数量,读写操作不能超过该限制。
  • 属性cap表示最大扩张容量,不能超出数组限制。
  • 如果slice == nil, 那么len、cap结果都等于0。
data := [...]int{
   
   0,1,2,3,4,5,6}
slice := data[1:4:5]         // [low:high:max]

读写操作实际目标是底层数组,只需注意索引号的差别。

data := [...]int{
   
   0,1,2,3,4,5}

s := data[2:4]
s[0] += 100
s[1] += 200

fmt.Println(s)
fmt.Println(data)

输出:

[102 103]
[0 1 102 203 4 5]

可直接创建slice对象,自动分配底层数组。

s1 := []int{
   
   0, 1, 2, 3, 8: 100}   //通过初始化表达式构造,可使用索引号。
fmt.Println(s1, len(s1), cap(s1))

s2 := make([]int, 6, 8)          //使用make创建,指定len和cap值。
fmt.Println(s2, len(s2), cap(s2))

s3 := make([]int, 6)             //省略cap,相当于cap = len。
fmt.Println(s3, len(s3), cap(s3))

输出:

[0 1 2 3 0 0 0 0 100] 9 9
[0 0 0 0 0 0]         6 8
[0 0 0 0 0 0]         6 6

使用make动态创建slice,避免了数组必须用常量做长度的麻烦。还可用指针直接访问底层数组,退化成普通数组操作。

s := []int{
   
   0, 1, 2, 3}
p := &s[2]            // *int,获取底层数组元素指针。
*p += 100

fmt.Println(s)

输出:

[0 1 102 3]

至于 [][]T,是指元素类型为[]T。

data := [][]int{
   
   
	[]int{
   
   1, 2, 3},
	[]int{
   
   100,  200},
	[]int{
   
   11, 22, 33, 44},
}

可直接修改struct array/slice 成员。

d := [5]struct
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值