【Go语言】笔记
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【Go语言】笔记,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6992字,纯文字阅读大概需要10分钟。
内容图文
未归档知识点
字符串末尾可以追加其他数据,但是不能修改原来的值
使用reflect包可以输出变量的类型
浮点数不指定默认是float64
package main
import ( "fmt";"reflect" )
func main() {
s := "aaa"
i := 10
f := 1.2
fmt.Println(reflect.TypeOf(s))
fmt.Println(reflect.TypeOf(i))
fmt.Println(reflect.TypeOf(f))
}
数据转换 资料
string ? bool
package main
import ( "fmt";"reflect";"strconv")
func main() {
var s string = strconv.FormatBool(true) // 举例:将bool类型转换成string
b,err := strconv.ParseBool(s) //举例:将string转化成bool, 会有两个返回值
fmt.Println(reflect.TypeOf(b),b,err)
}
output:
bool true <nil>
string ? int
package main
import ( "fmt";"strconv")
func main() {
s := strconv.Itoa(32)) // int -> string
i,_ := strconv.Atoi("3") // string -> int 成功
i,err := strconv.Atoi("a") // string -> int 失败
if err != nil { //判断是否成功
fmt.Println("converted failed", i) //i必须使用,这里的值为 0
}
}
Parse类函数
用于转换字符串为给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()
由于字符串转换为其它类型可能会失败,所以这些函数都有两个返回值,第一个返回值保存转换后的值,第二个返回值判断是否转换成功。
b, err := strconv.ParseBool("true")
f, err := strconv.ParseFloat("3.1415", 64) //ParseFloat()只能接收float64类型的浮点数。
i, err := strconv.ParseInt("-42", 10, 64) // func ParseInt(s string, base int, bitSize int) (i int64, err error)
u, err := strconv.ParseUint("42", 10, 64) // func ParseUint(s string, base int, bitSize int) (uint64, error)
bitSize
参数表示转换为什么位的int/uint,有效值为0、8、16、32、64。
当bitSize=0的时候,表示转换为int或uint类型。例如bitSize=8表示转换后的值的类型为int8或uint8。
base
参数表示以什么进制的方式去解析给定的字符串,有效值为0、2-36。
当base=0的时候,表示根据string的前缀来判断以什么进制去解析:0x开头的以16进制的方式去解析,0开头的以8进制方式去解析,其它的以10进制方式解析。
// 以10进制方式解析"-42",保存为int64类型
i, _ := strconv.ParseInt("-42", 10, 64)
// 以5进制方式解析"23",保存为int64类型
i, _ := strconv.ParseInt("23", 5, 64)
// 以16进制解析23,保存为int64类型
i, _ := strconv.ParseInt("23", 16, 64)
// 以15进制解析23,保存为int64类型
i, _ := strconv.ParseInt("23", 15, 64)
Format类函数
将给定类型格式化为string类型:FormatBool()、FormatFloat()、FormatInt()、FormatUint()
s := strconv.FormatBool(true)
s := strconv.FormatFloat(3.1415, ‘E‘, -1, 64) //func FormatFloat(f float64, fmt byte, prec, bitSize int) string
s := strconv.FormatInt(-42, 16) //func FormatInt(i int64, base int) string
s := strconv.FormatUint(42, 16) //func FormatUint(i uint64, base int) string
FormatInt的第二个参数base
指定将第一个参数转换为多少进制,有效值为2<=base<=36。当指定的进制位大于10的时候,超出10的数值以a-z字母表示。
FormatFloat()的参数
-
bitSize
表示f的来源类型(32:float32、64:float64),会据此进行舍入 -
fmt
表示格式:‘f‘(-ddd.dddd)、‘b‘(-ddddp±ddd,指数为二进制)、‘e‘(-d.dddde±dd,十进制指数)、‘E‘(-d.ddddE±dd,十进制指数)、‘g‘(指数很大时用‘e‘格式,否则‘f‘格式)、‘G‘(指数很大时用‘E‘格式,否则‘f‘格式) -
prec
控制精度(排除指数部分):对‘f‘、‘e‘、‘E‘,它表示小数点后的数字个数;对‘g‘、‘G‘,它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。
Append类函数
AppendTP类函数用于将TP转换成字符串后append到一个slice中:AppendBool()、AppendFloat()、AppendInt()、AppendUint()。
Append类的函数和Format类的函数工作方式类似,只不过是将转换后的结果追加到一个slice中
// 声明一个slice
b10 := []byte("int (base 10):")
// 将转换为10进制的string,追加到slice中
b10 = strconv.AppendInt(b10, -42, 10)
fmt.Println(string(b10))
b16 := []byte("int (base 16):")
b16 = strconv.AppendInt(b16, -42, 16)
fmt.Println(string(b16))
函数
函数可以有多个返回值
不定参数函数
// 实现求最大值函数
package main
import ( "fmt" )
func max(numbers ... int) int{
res := numbers[0]
for _,it := range numbers {
if res < it {
res = it
}
}
return res
}
func main() {
result := max(1,3,5,2,6)
fmt.Println(result)
}
具名返回值
指定返回值的名称,并在return前进行赋值,return时只需要裸return语句,可以增加函数的可读性
func sayHi() (x,y string) {
x = "Hello"
y = "world"
return
}
func main() {
fmt.Println(sayHi())
}
/*
output:
Hello world
*/
将函数作为值传递
package main
import ( "fmt")
func B(f func() string) string {
return f()
}
func main() {
fn := func() string {
return "ok"
}
fmt.Println(B(fn))
}
/*
output:
ok
*/
B接受一个签名类型为func() string
的函数作为函数参数f
,在B里面调用这个参数的函数f()
,就执行了这个函数,返回了一个string,再把这个函数作为返回值返回到main.
它同样也可以写成下面这种形式
func B(f func() string) string {
return f()
}
func A() string {
return "ok"
}
func main() {
fn := A
fmt.Println(B(fn))
}
流程控制
Golang中没有while关键词,while循环可以用for实现
// 打印1~10
func main() {
i:=0
for i<10 {
i++
fmt.Println(i)
}
}
类似C语言的迭代遍历,golang可以用for遍历数据结构
func main() {
a :=[]int{1,2,3,4}
for id,num := range a { //如果不需要序号‘id‘,可以用‘_‘代替
fmt.Println(id,"::",num)
}
}
/*
OUTPUT:
0 :: 1
1 :: 2
2 :: 3
3 :: 4
*/
defer语句
被defer指定的语句将在函数返回前执行,无论它被写在哪个位置
func main() {
defer fmt.Println("this is a defer function")
fmt.Println("hello world")
}
/*
OUTPUT:
hello world
this is a defer function
*/
如果程序里有多条defer语句,将从后往前执行
func main() {
defer fmt.Println("defer A")
defer fmt.Println("defer B")
fmt.Println("hello world")
defer fmt.Println("defer C")
}
/*
OUTPUT:
hello world
defer C
defer B
defer A
*/
一些需要使用defer语句的例子:
- 在读取文件后将其关闭
- 收到来自Web服务器的响应后对其进行处理以及建立连接后向数据库请求数据
- 需要在某项工作完成后执行特定的函数
数组,切片
切片类似于数组,但可以改变长度
append函数
使用append函数可以增大切片长度,也可以删除元素,不能将delete用于切片元素
func main() {
var d = make([]string, 2)
d[0] = "aaa"
d[1] = "bbb"
d = append(d,"ccc","ddd","eee") //向d的末尾添加多个元素
d = append(d[:2],d[3:]...) //删除d[2],将后面所有元素前移
for id,it := range d {
fmt.Println(id,it)
}
}
/*
OUTPUT:
0 aaa
1 bbb
2 ddd
3 eee
*/
copy函数
copy可以在新切片中创建元素的副本,但是不能改变新切片的长度
func main() {
a := []int {1,2,3,4}
a = append(a,5) //a的长度为5
b := make([]int, 2) //b的长度为2
copy(b,a)
fmt.Println(b)
}
/*
OUTPUT:
[1 2]
*/
映射
类似于c++的map
声明string → int空映射
var mp = make(map[string]int)
添加元素
mp["cook"] = 32
结构体
简单的例子
type Movie struct {
Name string
Year int
Rating float32
}
func main() {
m := Movie{Rating: 10, Name: "name", Year: 1999}
fmt.Println(m)// 直接打印是按照结构体定义成员变量的顺序打印
}
/*
OUTPUT:
{name 1999 10}
*/
还可以用new方法创建实例,但是创建的是指针变量
但是在golang中指针变量访问成员变量还是用‘.‘
type Movie struct {
Name string
Rating float32
}
func main() {
a := new(int)
//var a int
*a = 2333
fmt.Println(reflect.TypeOf(a))
m := new(Movie)
*m = Movie{
Name:"aaa",
Rating:9.9,
}
fmt.Println(reflect.TypeOf(m))
fmt.Println(m.Name, m.Rating)
}
/*
*int
*main.Movie
aaa 9.9
*/
结构体也是可以嵌套的,当作一个普通的数据类型,类似c++
创建结构体时,如果没有给数据字段指定值,那么为golang默认的初始值
golang没有提供自定义默认值的内置方法,但可以使用自定义函数来实现这个目标
方法、接口
类似于c语言的结构体,我们可以为结构体添加成员方法,在golang要写在结构体外面,在func之后,函数名之前添加“接收者”变量,传递指针还是传递值根据是否需要改变原值来决定。
type Movie struct {
Name string
Rating float64
}
func (m *Movie) summary() string {
r := strconv.FormatFloat(m.Rating, ‘f‘, 1, 64) //将float64转化成string
return m.Name + ", " + r
}
func main() {
m := Movie{
Name: "Spiderman",
Rating: 3.2,
}
fmt.Println(m.summary())
}
/*
OUTPUT:
Spiderman, 3.2
*/
接口描述了方法集中的所有方法,制定了它们的签名,但并没有实现他们。
要使用接口必须先实现它,接口定义了方法的规范,有助于代码理解
// 编写启动机器人的接口
type Robot interface {
PowerOn() error //不接受任何参数,返回一种错误类型
}
//编写两种机器人的启动方法
type T850 struct {
Name string
}
func (a *T850) PowerOn() error {
return nil
}
type R2D2 struct {
Broken bool
}
func (r *R2D2) PowerOn() error {
if r.Broken {
return errors.New("R2D2 is broken")
} else {
0 return nil
}
}
//编写一个可用于启动任何机器人的函数, 这个函数将接口的实现作为参数
func Boot(r Robot) error {
return r.PowerOn()
}
//各种调用方法
func main() {
t := T850{Name: "The Terminator"}
r := R2D2{Broken: true}
err := Boot(&r)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Robot is powered on!")
}
err = Boot(&t)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Robot is powered on!")
}
}
/*
OUTPUT:
R2D2 is broken
Robot is powered on!
*/
接口有助于代码重用,还能完全更换实现,在golang中,接口一声明的方式提供了多态
原文:https://www.cnblogs.com/greenty1208/p/13049328.html
内容总结
以上是互联网集市为您收集整理的【Go语言】笔记全部内容,希望文章能够帮你解决【Go语言】笔记所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。