接着上一篇的基础知识,这篇结束,基本上Go语言的大概就没啥问题了,其余的跟其他语言都不会有多大差别,毕竟语言只是一门工具,核心还是算法,有兴趣的可以关注下面这个专栏数据结构+算法(Algorithm)icon-default.png?t=M85Bhttps://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,关于测试你学会了吗?