接着上一篇的基础知识,这篇结束,基本上Go语言的大概就没啥问题了,其余的跟其他语言都不会有多大差别,毕竟语言只是一门工具,核心还是算法,有兴趣的可以关注下面这个专栏数据结构+算法(Algorithm)
https://blog.csdn.net/weixin_41896770/category_9329529.html其实算法也不难,简单来说就是一种处理问题的思路,算法会了,不同语言的移植也是比较快速的
捕获错误
将greetings.go修改为如果没有指定名字,就显示出错信息。也可以返回多个值,一个是字符串类型,一个是错误类型。
greetings.go
package greetings
import (
"fmt"
"errors"
)
//返回两个类型的值,string与error
func Hello(n string)(string,error){
if n==""{
return "",errors.New("名字为空!")
}
message := fmt.Sprintf("Hi, %v. You're a good man!", n)
return message,nil
}
我们在hello.go中来捕获这个错误
hello.go
package main
import (
"fmt"
"example.com/greetings"
"log"
)
func main() {
log.SetPrefix("greetings: ")//可以设置前缀
log.SetFlags(0)//不打印时间,源文件,行号等
message,err := greetings.Hello("")
if err != nil{
log.Fatal(err)
}
fmt.Println(message)
}
/*
C:\Users\Tony\hello>go run hello.go
2022/10/25 08:35:53 名字为空!
exit status 1
*/
/*
C:\Users\Tony\hello>go run hello.go
greetings: 名字为空!
exit status 1
*/
slice切片
这里是用字符串数组,然后初始化一个随机种子,之后随机索引获取随机问候
greetings.go
package greetings
import (
"fmt"
"errors"
"math/rand"
"time"
)
//返回两个类型的值,string与error
func Hello(n string)(string,error){
if n==""{
return "",errors.New("名字为空!")
}
message := fmt.Sprintf(randomFormat(), n)
return message,nil
}
//随机初始化种子,将时间转成整型
func init() {
rand.Seed(time.Now().UnixNano())
}
//随机索引,选取
func randomFormat() string {
//[]string注意数组写法
formats := []string{"Hi, %v. Welcome!","Great to see you, %v!","Hail, %v! Well met!",}
return formats[rand.Intn(len(formats))]
}
hello.go
package main
import (
"fmt"
"example.com/greetings"
"log"
)
func main() {
log.SetPrefix("greetings: ")//可以设置前缀
log.SetFlags(0)//不打印时间,源文件,行号等
message,err := greetings.Hello("Tony")
if err != nil{
log.Fatal(err)
}
fmt.Println(message)
}
/*
C:\Users\Tony\hello>go run hello.go
Hi, Tony. Welcome!
C:\Users\Tony\hello>go run hello.go
Hail, Tony! Well met!
*/
for循环
Go中的for循环跟其他语言比较有很大区别,我们来看一个多人随机问候的示例
greetings.go
package greetings
import (
"fmt"
"errors"
"math/rand"
"time"
)
//返回两个类型的值,string与error
func Hello(n string)(string,error){
if n==""{
return "",errors.New("名字为空!")
}
message := fmt.Sprintf(randomFormat(), n)
return message,nil
}
//数组参数,注意map的写法,是一个无序的键值对集合
func Hellos(names []string)(map[string]string,error){
messages:=make(map[string]string)
for _,n:=range names{
message,err:=Hello(n)
if err!=nil {
return nil,err
}
messages[n]=message
}
return messages,nil
}
//随机初始化种子,将时间转成整型
func init() {
rand.Seed(time.Now().UnixNano())
}
//随机索引,选取
func randomFormat() string {
//[]string注意数组写法
formats := []string{"Hi, %v. Welcome!","Great to see you, %v!","Hail, %v! Well met!",}
return formats[rand.Intn(len(formats))]
}
hello.go
package main
import (
"fmt"
"example.com/greetings"
"log"
)
func main() {
log.SetPrefix("greetings: ")//可以设置前缀
log.SetFlags(0)//不打印时间,源文件,行号等
names := []string{"Tony", "寅恪光潜", "Jay Chou"}
messages,err := greetings.Hellos(names)
if err != nil{
log.Fatal(err)
}
fmt.Println(messages)
}
/*
C:\Users\Tony\hello>go run hello.go
map[Jay Chou:Hail, Jay Chou! Well met! Tony:Great to see you, Tony! 寅恪光潜:Hail, 寅恪光潜! Well met!]
*/
其中关于上面map和make的用法,看个示例就明白了
package main
import "fmt"
func main() {
var m map[string]string
m = make(map[string]string)
m["Tony"] = " good man"
m["ChyiChin"] = "singer"
m["爱因斯坦"] = "scientist"
fmt.Println("m=", m)
}
//m= map[ChyiChin:singer Tony: good man 爱因斯坦:scientist]
test
可以测试程序在实际运行的时候,找出bug然后可以进行改正,这个测试很有意思,将文件名称加上后缀_test,这样就是显示说明这个文件里面包含测试函数
新建一个测试文件试下,在greetings目录下面,文件名为:greetings_test.go
package greetings
import (
"fmt"
"errors"
"math/rand"
"time"
)
//返回两个类型的值,string与error
func Hello(n string)(string,error){
if n==""{
return "",errors.New("名字为空!")
}
message := fmt.Sprintf(randomFormat(), n)
return message,nil
}
//数组参数,注意map的写法,是一个无序的键值对集合
func Hellos(names []string)(map[string]string,error){
messages:=make(map[string]string)
for _,n:=range names{
message,err:=Hello(n)
if err!=nil {
return nil,err
}
messages[n]=message
}
return messages,nil
}
//随机初始化种子,将时间转成整型
func init() {
rand.Seed(time.Now().UnixNano())
}
//随机索引,选取
func randomFormat() string {
//[]string注意数组写法
formats := []string{"Hi, %v. Welcome!","Great to see you, %v!","Hail, %v! Well met!",}
return formats[rand.Intn(len(formats))]
}
C:\Users\Tony\greetings>go test
PASS
ok example.com/greetings 0.230s
如果name := "Tony1"测试就会报错:
C:\Users\Tony\greetings>go test
--- FAIL: TestHelloName (0.00s)
greetings_test.go:15: Hello("Tony") = "Hail, Tony! Well met!", <nil>, want match for `\bTony1\b`, nil
FAIL
exit status 1
FAIL example.com/greetings 0.227s
还可以详细输出,加一个-v选项
C:\Users\Tony\greetings>go test -v
=== RUN TestHelloName
--- PASS: TestHelloName (0.00s)
=== RUN TestHelloEmpty
--- PASS: TestHelloEmpty (0.00s)
PASS
ok example.com/greetings 0.228s
修改greetings_test.go中的Hello函数
//message := fmt.Sprintf(randomFormat(), n)
message := fmt.Sprintf(randomFormat())
去掉没有名字这项,我们来看下测试的结果
C:\Users\Tony\greetings>go test
--- FAIL: TestHelloName (0.00s)
greetings_test.go:15: Hello("Tony") = "Hail, %!v(MISSING)! Well met!", <nil>, want match for `\bTony\b`, nil
FAIL
exit status 1
FAIL example.com/greetings 0.237s
可以看出%v是缺失的,我们想要匹配的是Tony,这样就会显示bug,关于测试你学会了吗?