服务计算(2):go环境配置与学习

Go语言学习

环境配置

使用yum install

使用命令sudo yum install -y golang

直接下载安装包

环境:腾讯云主机 Ubuntu 16.04

具体见官方文档

  • 首先下载安装包:wget https://studygolang.com/dl/golang/go1.11.linux-amd64.tar.gz(请自行选择要下载的安装包)
  • linux可以选择直接解压到/usr/local中,sudo tar -C /usr/local -xzf go1.11.linux-amd64.tar.gz,会在目标目录建立一个go的文件树,安装完成一半
  • 使用vim ~/.bashrc打开配置文件,然后输入export PATH=$PATH:/usr/local/go/bin配置环境变量,使用source ~/.bashrc刷新环境变量。
  • 因为我用的是vim,所以安装就到此为止了。

环境2:本地虚拟CentOS主机

  • 使用sudo yum install golang安装go
  • 设置环境变量,我用的是~/go作为工作空间,环境变量为export GOPATH=$HOME/goexport PATH=$PATH:$GOPATH/bin,与ubuntu不同,用户配置文件为~/.profile,同样是使用source ~/.profile刷新环境变量。

验证安装是否成功

在默认工作区(linux下为~/go)下创建/src/hello,并写下下面代码:

package main

import "fmt"

func main() {
	fmt.Printf("hello, world\n")
}

然后尝试编译go build,如果没有错误信息,尝试运行./hello。如果看到hello,world,则安装成功。
如果想要改变工作区位置,看这里

与远程库关联

  1. 首先查看用户主目录下是否存在.ssh目录。没有的话,使用命令ssh-keygen -t rsa -C "youremail@mail.com"来创建SSH Key,然后将.ssh目录下的id_rsa.pub文件里的公约复制,在Github界面Settings的SSH and GPG Keys界面下,点击SSH Keys上的Add new并粘贴,取个Title,再确定。
  2. 使用git init创建本地仓库,然后使用git remote add origin git@github.com:wtysos11/sysu-goLearning.git完成远程库关联。
  3. 使用git commit提交第一次操作,然后使用git push origin -u master把主分支提交上远程库。

官方教程

快速入门

使用菜鸟教程进行快速入门,用作建立整体印象。要想细致学习推荐官方文档的language specification,挺好的,就目前而言比我看到的绝大多数资料讲的都要清楚有用,但是太长了,我还没看完老师就发了石墨文档,就先不写了。

数据类型

没太多好说的,比较类似于java,略过。
string近似于常量,不能够使用下标访问改变内容。

变量

变量声明有三种方式,一种是使用var identifier type的形式声明后,使用=进行变量赋值;一种是省略前一种中的type,让编译器自行判断类型;还有一种是使用:=进行赋值,但是要求左侧的变量之前没有被声明过,不然会导致编译错误。

go的多变量赋值可以使用类似于Python的形式,即vname1,vname2,vname3 = v1,v2,v3,会给每个变量进行分别赋值。

go与C++类似,存在值类型和引用类型,以及指针等概念。

可以使用const声明常量

比较特殊的是iota,即特殊长安令,在const关键字出现时被设为0,const中没新增一行常量就会计数一次,常规用法如下:

const(
	a = iota
	b = iota
	c = iota
)

这样子与a=0,b=1,c=2等价。还有一些比较厉害的操作,我也讲不清楚,需要自行查阅相关文档。虽然我觉得大部分人也不会用就是了。

运算符

C系列,略过

条件语句

注意左大括号{不能单独成行,不然会有编译错误。
switch语句中的case可以为任意类型,而不是像C一样需要能够转化为整形才能使用。形式类似,但是不用加break,一旦匹配到一个case后会默认退出。如果加上fallthrough关键字后会继续往下进行。可以使用break关键字。
其中switch语句可以使用type-switch来判断摸个interface变量中实际存储的变量类型,需要自行查阅。

select:我也没用过。

循环语句

for语句相当于C语言不加左右括号的版本,两个分号如果省略的话与while是等价的。存在Goto,类似于python中的版本,可以跳转到标记行。但是break和continue是C中的,只能在当前循环进行操作(应该)

函数

格式:

func function_name([parameter list]) [return_types]{
}

其中func为关键字,后面分别是函数名,参数列表和返回类型。需要注意的是,返回类型可以为多个,也就是说可以同时返回多个值。

函数传参方式与Verilog和python类似,除了按照顺序传参,还可以直接使用函数中的变量名称进行传参。

方法:
格式

func (variable_name variable_data_type) function_name([parameter list]) [return_types]{
}

就是多了前面那个,表示是某个结构体的方法。

数组

声明类似与java看,格式:var variable_name[SIZE] variable_type,多维数组直接使用多个[]即可。可以使用{}进行初始化,如var balance = [5]float32{1000.0,2.0,3.4,7.0,50.0},如果[]中没有数字,会按照后面元素的个数来设置数组的大小。

使用下标来访问数组元素,向函数传递数组也是与java类似,即在参数列表中输入形为param [10]int,其中数组大小的省略与否与C类似。

指针

与C类似,目前还没看出有什么不同的,初学阶段可以默认相同。

结构体

go没有面向对象的特性,结构体只是不同类型数据的有序集合。
需要使用type和struct来定义结构体,如:

type struct_variable_type struct{
	member definition
}

如前所述,可以为结构体声明方法。
结构体赋值与C++等类似,即variable_name := struct_variable_type {value1,...}或是variable_name:=struct_variable_type{key1:value1,...}

切片(slice)

slice是对数组的抽象,它是基于实际存在数组的。
因为Go数组长度不可改变,所以会有问题。slice可以改变元素的数量。
可以声明一个未知大小的数组来定义切片,如:var identifier []type,或是使用make函数var slice1 []type = make([]type,len),也可以指定容量,容量大小为make的第三个参数(可选)
初始化与数组一样,可以如python和js以及matlab等用:进行范围访问。len()方法获取长度,cap()方法获取切片的最大值(到达最大值后可以创建新的切片然后使用copy()方法进行转移),append()方法用于追加新的元素

范围(range)

类似与python中的enumerate,range可以对一个数组产生一个元组迭代序列,即

nums := []int{2,3,4}
sum := 0
for _,num := range nums{
	sum += num
} 

其中_为空白占位符,类似与haskell,在这里表示的是忽略index值,得到的num即为元素的值。通过这一操作,可以实现数组求和。

Map

无序的键值对集合,与C++STL中的同名结构以及python中的dict类似。
使用内建函数make可以创建map

var map_variable map[key_data_type]value_data_type
map_variable := make(map[key_data_type]value_data_type)

使用delete函数删除键对应的值。

类型转换

与C++等类似,使用type_name(expression)可以将expression中的值转换为type_name的类型。

接口

一种数据类型,可以将所有具有共性的方法定义在一起。其他类型只要实现了这些方法就是实现了这个接口

/* 定义接口 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* 定义结构体 */
type struct_name struct {
   /* variables */
}

/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* 方法实现*/
}

错误处理

error类型是一个接口类型,定义为

type error interface{
	Error() string
}

与node.js类似,go的函数会与error对象相关联,不过js是在回调函数的第一个参数,error是返回值的第二个参数

读书记录

Cloud Native Go : 构建基于Go和React的云原生Web应用与微服务的读书记录,方便日后复习

1.云之道

cloud native:明确地关注应用而不是人和设计哲学,并且依赖于原始的“12要素法则”来定义和描绘应用程序。

云之道的优点

云之道改变了程序员对于软件开发的看法,把他们从重复添加功能、部署并祈祷其正常运行的艰难时刻中解脱出来,使软件开发再次成为乐趣。

规则:

  • 遵循简单。质疑一切事物似乎违背简单性,如无必要,不应额外添加新的复杂流程;质疑每个工具是否必要;质疑所有的代码是否过于复杂以至于无法阅读。
  • 测试优先,测试一切。测试提供信心,信心战胜对未知的恐惧;使用单元测试可以让信心指数上升。
  • 尽早发布,频繁发布。将每次代码提交都当作潜在的生产发布,并通过持续交付流水线进行部署。
  • 自动化一切。任何每天做的超过一次的事情,都适合自动化;流程中任何时常重复的部分,如果不能被按钮或脚本所取代,那么就属于复杂、脆弱或两者兼有之的部分。
  • 建立服务生态系统。任何事物都是服务,包括应用。(微服务遵循了单一责任原则SRP,即源于面向对象的设计模式,一个服务只负责一个功能)

使用GO的原因:

  1. 简单
  2. 开源
  3. 易于自动化和IDE自动化

2.开始

配置环境

Mac需要安装Homebrew。
安装Mercurial和Bazaar(第三方Go包的来源,这两个都是版本控制系统)

实操记录:我在使用腾讯云提供的Ubuntu14.04LTS通过sudo apt-get install bazaar安装bazaar时反馈没有这个包,根据官方的说明,应该使用apt-get install bzr命令进行安装。
Mercurial的关联命令是hg,bazaar的关联命令是bzr。

可以通过go get命令从github上获取代码。

3.Go入门

使用基本函数

GO并不是面向对象的语言,GO中没有类,只有函数,这些函数的可见性由包的范围以及函数是否可以导出决定。
Go中可以实现完全的柯里化(把接受多个参数的函数变为接受一个参数的函数,并且返回接受其他参数和返回结果的新函数)

使用结构体

GO中的结构体只是字段的类型化集合,可以嵌套使用,也可以创建匿名结构体。
从type关键字开始,例如

type person struct{
	name string
	age int
}

可以使用不同的方式创建结构体,下面的代码都可以用来创建一个person结构体

var p = person{}
var p2 =  person{"bob",21}
var p3 = person{name:"bob",age:21,}

或者在person前加&也是可以的,会创建一个指向person结构体的指针。
第一行表示如何创建一个空的结构体,第二行表示通过定义字段的顺序使我们可以顺序地赋初始值。第三行允许我们以任何我们喜欢的顺序为字段赋值,因为它标明了字段的名称(类似于python)

介绍Go接口
向结构体添加方法

可以使用结构体(实际上几乎是任何类型)来锚定方法,这意味着可以拥有专门用于结构体的函数。

注意:如果名称与数据类型匹配,则不必重复声明两次,比如这样:

type attacker struct{
	attackpower int
	dmgbonous int
}
type sword struct{
	attacker
	twohanded bool
}

下面使用Go的语法来为结构体添加Wield方法

func (s sword) Wield() bool{
	fmt.Println("You've wielded a sword!")
	return true
}
Go中的接口动态类型检查

可以使用以下的简单代码声明一个指示某物是武器的接口:

type weapon interface {
	Wield() bool
}

与其他语言不同的是,go中不必去声明一个结构体或者其他类型是一个武器,它能够凭借Go是否能够在一定范围内找到指定签名的方式自动被识别。
现在可以创建下面的函数:

func wielder (w weawpon) bool{
	fmt.Println("Wielding ...")
	return w.Wield()
}

现在就可以把sword变量传给wielder函数了。
因此只要类型满足一个接口,它就可以在任何使用该接口的地方使用。(大概就是我要一个修空调的人,不管是空调师傅还是物业阿姨,只要能修都是可以的)

创建自有包
导出函数和数据

软件包是Go中的一个访问范围单位,虽然没有OOP中的成员访问关键字,但是仍然可以控制代码的可见性。我们在Go中创建的任何以小写字母开头的类型(或函数)都被认为是包所私有的或者没有导出的。我们创建的任何以大写字母开头的类型都会被导出,任何使用该包的人都可以看到。

创建包

首先创建如下没有的目录$GOPATH/src/github.com/cloudnativego/go-primer/npcs,这意味着将在这个目录下工作。
按照惯例,许多软件开发人员更喜欢创建一个types.go文件,其中包含要由软件包使用或导出的类型,例如以下这个。

package npcs

// Power describes the attack and defense power of the NPC
type Power struct {
	Attack int
	Defense int
}

// Location describes where in the virtual world an NPC exists
type Location struct {
	X float64
	Y float64
	Z float64
}

// NonPlayerCharacter represents metadata for an in-game creature
type NonPlayerCharacter struct{
	Name string
	Speed int
	HP int
	Power Power
	Loc Location
}

所有向包使用者暴露的方法会放在一个名为npcs.go的单独文件中:

package npcs

import (
	"fmt"
	"math"
)

func (loc Location) String() string{
	return fmt.Sprintf("(%f,%f,%f)",loc.X,loc.Y,loc.Z)
}
...

所有的导出函数都需要以大写字母开头,同时它们所操作的结构体和字段也已经被导出了。
创建完这个子包之后,就可以在客户端应用程序中使用它了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值