学习golang的历程——持续更新
Posted zhoulixiansen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习golang的历程——持续更新相关的知识,希望对你有一定的参考价值。
学习一门语言首先hello world
1,首先建立一个目录,新建一个hello.go的文件
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
2,go run hello.go
jack_zhou@zhoulideMacBook-Pro study % go run hello.go
hello world
上面我们就完成了我们的基础使命。下面我们正式开始入门
在正式进入写代码之前,推荐大家使用JB家族的Goland
在设置中需要注意GOPATH和GOROOT不能写同一个地址,否则会报错:
warning: GOPATH set to GOROOT (/usr/local/go) has no effect
一,入门篇
1,golang语言特性
① 垃圾回收
- 内存自动回收,不需要开发人员管理内存
- 开发人员只需关注业务实现,降低负担
- 只需new分配内存,不需要释放
② 天然并发
- 从语言层面支持并发,非常简单
- goroute,轻量级线程,创建成千上万个goroute成为可能
- 基于CSP(Communicating Sequential Process)模型实现
③ 管道(channel)
- 管道,类似unix/linux中的pipe
- 多个goroute之间通过channel进行通信
- 支持任何类型
④ 多返回值
- 定义函数返回类型需要加括号
- 返回需要以,作为分隔
⑤ 需要编译
go build + 路径
2,变量的定义:
# 第一种package变量
var (
a = 1
b = 2
)
var aa = true
# 第二种非package变量
var a, b int = 1, 2
# 简写
var a,b = 1, "89"
# 精简
a, b := 1, "78" // 全局不可使用
在上一个例子的基础上写一个加法函数,传入两个变量,返回两个参数之和
package main
import (
"fmt"
)
func add(a int, b int) int {
var sum int
sum = a + b
return sum
}
func main() {
var c int
c = add(100, 200)
fmt.Println("hello world!", c)
}
在上述例子中,我们可以看到,他是没有封号的
在定义变量的时候需要指定比变量的类型,定义函数的时候,在()外需要写上返回值的类型
需要注意的是,go不容许定义变量而不使用的情况发生,否则编译的时候就会报错,比如:
c declared and not used
3,包的定义
- 和Python语言,把相同功能代码放到一个目录中,称之为包(因此,在写代码的时候都需要写package 包名)
- 包当然支持被其他包的引用
- main包是用来生成可执行文件,每一个程序有且只能有一个main包
- 包的主要用途是提高代码的可复用性
4,注意事项
① Go 进行build的时候经常会遇到 can‘t load package
在Goland中配置
需要加上Project GOPATH 路径
② Go新建项目默认需要在src下,并且,编译的时候不需要将src路径写入
go默认所有的项目文件都放在src目录下面
在project目录下执行go build go_test/day1/example即可
③ 一般build文件都指定在一个bin目录
go build -o bin/calc go_dev/day1/package_count/main
用 -o 来指定目录bin,文件为calc,编译的是main
5,go的基本类型
① 文件名&关键字&标识符
[x] 所有源码以.go结尾
[x] 标识符以字母或者下划线开头,大小写敏感(_)
[x] _是特殊标识符,用来忽略结果
[x] 保留关键字
break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
② Go程序基本结构
任何一个代码文件隶属于一个包
import 关键字,引用其他包
import ("fmt") import ("os") // 通常写为 import ( "fmt" "os" )
Golang 可执行程序,package main,并且有且只有一个main函数入口
包内函数调用,直接调用
不同包内调用函数,需要通过包名 + 点 + 函数名进行调用(函数名首字母必须大写)
package main import "fmt" func list(n int) { for i := 0; i <= n; i++ { fmt.Println("%d+%d=%d ", i, n-i, n) } } func main() { list(10) } // 打印循环
[x] 注意:在包中可以定义一个init函数,默认会在main执行之前执行
package calc var Name string = "jack" var Age int = 10 func init() { Name = "zhou" Age = 100 } // 最终结果是Name为zhou,Age为100 // 执行顺序 先执行全局变量,在执行init,最后到main
③ 常量和变量
一,常量
常量使用const修饰,代表永远是只读的,运行期间不能够修改
const只能修饰boolean,number(int相关类型、浮点类型、cpmplex)和string
语法:const identifier [type] = value,其中type可以省略。
const b string = "hello world" const b = "hello world" const Pi = 3.1415926 const a = 9.3 const c = getValue() // 错误,因为常量是不可改变的
单行注释 // 多行注释 /* */(其实和JS的写法一致的)
二,变量
见上方变量的定义
④ 数据类型和操作符
一,数据类型
值类型: 基本数据类型int,float, bool, string以及数组和struct
当值类型需要修改的时候 传入值之前加一个&即可,比如:
modify(a) ---->>> modify(&a)
这样就相当于传入a的内存地址到modify中去
引用类型: 指针,slice,map, chan等都是引用类型
二,操作符
逻辑操作符
== 、!=、<=、>=、>、<、!、&&、 ||
func main() { a := 10 if (a > 2) { fmt.Println(a) } }
数学操作符
+、-、*、/ 等等
⑤ 字符串类型
func main() {
var str = "hello world
"
var str1 = `
窗前明月光,
地上鞋两双。
`
var b byte = 'c'
fmt.Println(str)
fmt.Println(str1)
fmt.Println(b)
fmt.Printf("%c
", b)
}
go在进行输出的时候是不会改变原有的样式的,对于打印bytes对象,会直接打印对于字符表中的具体位置的
fmt文档:给您放这里啦
例子: 交换两个变量的值
package main
import (
"fmt"
_ "os"
)
func swap(a int, b int) {
tem := a
a = b
b = tem
return
}
func main() {
first := 100
second := 200
swap(first, second)
fmt.Println(first, second)
}
结果如下:
jack_zhou@zhoulideMacBook-Pro ~ % /Users/jack_zhou/workspace/gospace/project/main ; exit;
100 200
为啥没有产生变化呢?
因为这两个变量属于值类型的,值类型是属于复制拷贝,改的是副本的值,如果需要改就必须传入指针地址。那如何修改呢?
package main
import (
"fmt"
_ "os"
)
func swap(a *int, b *int) {
tem := *a
*a = *b
*b = tem
return
}
func main() {
first := 100
second := 200
swap(&first, &second) // 传入变量的地址
fmt.Println(first, second)
}
结果如下:
Last login: Sun Dec 8 22:55:57 on ttys002
jack_zhou@zhoulideMacBook-Pro ~ % /Users/jack_zhou/workspace/gospace/project/main ; exit;
200 100
package main
import (
"fmt"
_ "os"
)
func swap(a int, b int) (int, int) {
tem := a
a = b
b = tem
return a, b
}
func main() {
first := 100
second := 200
first, second = swap(first, second) // 传入变量的地址
fmt.Println(first, second)
}
通过返回值的方式也是可以的
最简单的方式是:
package main
import (
"fmt"
_ "os"
)
func main() {
first := 100
second := 200
first, second = second, first
fmt.Println(first, second)
}
写到这突然发现还是Python大法好啊╮( ̄▽ ̄)╭
⑥ 字符串的操作
直接相加
package main import "fmt" func main() { var str = "hello" var str2 = " world" str3 := str+str2 fmt.Println(str3) }
格式化输出
package main
import "fmt"
func main() {
var str = "hello"
var str2 = " world"
// str3 := str+str2
str3 := fmt.Sprintf("%s %s", str, str2) // 格式化输出
fmt.Println(str3)
}
求字符串长度
package main import "fmt" func main() { var str = "hello" var str2 = " world" // str3 := str+str2 str3 := fmt.Sprintf("%s %s", str, str2) // 格式化输出 n := len(str3) fmt.Printf("len(str)=%d ", n) }
字符串的切片
package main import "fmt" func main() { var str = "hello" var str2 = " world" // str3 := str+str2 str3 := fmt.Sprintf("%s %s", str, str2) // 格式化输出 substr := str3[0:5] // 和Python操作一致 fmt.Println(substr) }
字符串反转
package main import "fmt" func reverse(str string) string { var result []byte tmp := []byte(str) // 强制转换字符数组 length := len(str) for i := 0; i < length; i++ { result = append(result, tmp[length-i-1]) } return string(result) } func main() { var str = "hello" var str2 = " world" str3 := str + str2 result := reverse(str3) fmt.Println(result) }
以上是关于学习golang的历程——持续更新的主要内容,如果未能解决你的问题,请参考以下文章