Go语言在循环中panic后还能继续执行for循环?

Go语言在循环中panic后还能继续执行for循环?,第1张

如下的例子,要打印100以内能被5整除的数,以panic的方式选择出来并打印。 如果用下面的方式,执行到第一个panic就会跳出for循环 只能输出第一个匹配项,然后退出for循环。 那么如何保证在for循环处理完panic不退出循环,直到打印完所有满足条件的数值? golang的panic被恢复后,能继续执行比recover更早的defer,或者返回到recover函数的调用方,然后继续执行下去。 所以,我们可以把panic和recover放到单独的函数中,然后在for循环里调用这个函数,这个函数panic并恢复后,能返回到调用方for循环并继续循环下去。 执行结果是所有0到100的所有符合panic条件的都能正确处理,for循环没有异常退出: golang的panic属于非常严重的错误,一旦panic没有recover的话,程序就退出了。一般避免主动panic,影响程序稳定性。 recover函数要放在defer里面,并且只能恢复同一个goroutine的并且是直接调用链函数发生的panic。recover不能恢复上一层函数的panic。

mysql不像 SQL Server,写一段SQL,要go了才执行,默认 分号就执行了。

在网上找了一大堆例子,最后简化一下把,一下会从安装mysql开始,与大家分享一下如何用go链接服务器上的mysql

我用的是ubuntu系统

1,安装mysql:sudo apt-get install mysql-server (记住root的密码假设密码为root123)

2,进入mysql:mysql -uroot -p 然后输入密码

3,创建一个数据库:create database people

4,给数据库people添加用户:GRANT ALL PRIVILEGES ON people.* TO peo@localhost IDENTIFIED BY "peo123"

5,调整数据库配置以便于远程访问:GRANT ALL PRIVILEGES ON people.* TO peo@“%” IDENTIFIED BY "peo123"然后推出mysql执行:sudo nano /etc/mysql/my.cnf

修改bind-address=127.0.0.1 到bind-address= 机器的IP(就是安装mysql的机器的ip)

6,重启mysql:sudo /etc/init.d/mysql restart

7,建表:首先进入mysql:mysql -u peo -p

进入数据库下:use people

创建表:create table hello(age int, name varchar(10))

插入一条数据:insert into hello(age, name) values(19, "hello world")

至此数据库方面的工作已经做好,接下来是go语言了

8,首先下载mysql的驱动包(应该是这样叫)执行 go get github.com/go-sql-driver/mysql代码会下载到你的gopath下(执行export可以查看gopath)

接着就是下面的代码了

package main

import "database/sql"

import _ "github.com/go-sql-driver/mysql"

import "encoding/json"

import "fmt"

type User struct {

Age int `json:"age"`

Name string `json:"name"`

}

func main() {

fmt.Println("start")

db, err := sql.Open("mysql", "peo:peo123@tcp(192.168.0.58:3306)/people?charset=utf8")

if err != nil {

panic(err)

}

rows, err := db.Query("select age,name from hello")

if err != nil {

panic(err)

}

defer rows.Close()

for rows.Next() {

user := &User{}

err = rows.Scan(&user.Age, &user.Name)

if err != nil {

painc(err)

}

b, _ := json.Marshal(user)

fmt.Println(string(b))

}

println("end")

}

至此结束

大家经常用"=="来比较两个变量是否相等。但是golang中的"=="有很多细节的地方,跟php是不一样的。很多时候不能直接用"=="来比较,编译器会直接报错。

golang中基本类型的比较规则和复合类型的不一致,先介绍下golang的变量类型:

golang中的基本类型

比较的两个变量类型必须相等。而且,golang没有隐式类型转换,比较的两个变量必须类型完全一样,类型别名也不行。如果要比较,先做类型转换再比较。

复合类型是逐个字段,逐个元素比较的。需要注意的是, array 或者struct中每个元素必须要是可比较的,如果某个array的元素 or struct的成员不能比较(比如是后面介绍的slice,map等),则此复合类型也不能比较。

逐个成员比较类型和值。每个对应成员的比较遵循基本类型变量的比较规则。

但是如果struct中有不可比较的成员类型时:

可以看到,struct中有slice这种不可比较的成员时,整个struct都不能做比较,即使没有对slice那个成员赋值(slice默认值为nil)

slice和map的比较规则比较奇怪,我们先说普通的变量引用类型&val和channel的比较规则。

引用类型变量存储的是某个变量的内存地址。所以引用类型变量的比较,判断的是这两个引用类型存储的是不是同一个变量。

上面看起来比较废话,但是得理解引用类型的含义。不然对判断规则还是不清楚。

slice类型不可比较,只能与零值nil做比较。

关于slice类型不可比较的原因,后面会专门写文章做讨论。

map类型和slice一样,不能比较,只能与nil做比较。

接口类型的变量,包含该接口变量存储的值和值的类型两部分组成,分别称为接口的动态类型和动态值。 只有动态类型和动态值都相同时,两个接口变量才相同:

而且接口的动态类型必须要是可比较的,如果不能比较(比如slice,map),则运行时会报panic。因为编译器在编译时无法获取接口的动态类型,所以编译能通过,但是运行时直接panic:

golang的func作为一等公民,也是一种类型,而且不可比较

上面说过,map和slice是不可比较类型,但是有没有特殊的方法来对slice和map做比较呢,有

reflect.DeepEqual函数可以用来比较两个任意类型的变量

对map类型做比较:

对slice类型做比较:

对struct类型做比较:

可以发现,只要变量的类型和值相同的话,reflect.DeepEqual比较的结果就为true

直接看用例:

结果为:

1, golang的类型再定义和类型别名

2,golang的slice和map为什么不可以比较

1, https://medium.com/golangspec/equality-in-golang-ff44da79b7f1

2, https://studygolang.com/articles/19144

3, https://juejin.im/post/5d5ff27d518825637965f3f3


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/8578327.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-18
下一篇2023-04-18

发表评论

登录后才能评论

评论列表(0条)

    保存