断言
- 格式: t,ok:=i.(T) 【t:就是i接口是T类型的,i:接口,T:类型】
func assertInt(i any) {
i, ok := i.(int)
fmt.Println(i, ok)
if ok {
fmt.Println("int类型")
} else {
fmt.Println("非int类型")
}
}
switch 实现断言不中断
package main
import "fmt"
type MyType struct{}
func assertDifferentType(i any) {
switch i.(type) {
case MyType:
fmt.Println("MyType")
case int:
fmt.Println("int")
case float64:
fmt.Println("float64")
case string:
fmt.Println("string")
case interface{}:
fmt.Println("empty interface")
case nil:
fmt.Println("nil")
default:
fmt.Println("未知类型")
}
}
func main() {
assertDifferentType("1")
assertDifferentType(1)
assertDifferentType(1.2)
var nilVariable MyType
assertDifferentType(nilVariable)
var emptyInterface interface{}
assertDifferentType(emptyInterface)
var mt = MyType{}
fmt.Println(mt)
assertDifferentType(mt)
}
Type 关键字,自定义新类型
- 定义结构体 : type xxx struct{}
- 定义接口 : type xx interface{}
- 自定义类型。 newType : type newInt int 。 【newInt 和 int 属于两种类型。不同类型不能计算 】
- 给 某个已有类型 起别名 : type anotherNameType = int 【anotherNameType 还是 int 类型】
package main
import "fmt"
type myType2 int
func main() {
var i int = 1
fmt.Println("i=", i)
var i2 myType2 = 1
fmt.Printf("i2 【值】:%v,【类型】%T\n", i2, i2)
fmt.Println("i 是 int 类型。 i2 是 main.myType2。 虽然main.myType2继承于int。但是 i 和 i2 不能做同类型计算")
type myType3 = int
var i3 myType3 = 100
fmt.Printf("i3 【值】:%v,【类型】%T\n", i3, i3)
fmt.Println("i 是 int 类型。 i3 是 int。 i 和 i3 是同类型,可以计算")
}
异常和错误的区别
package main
import (
"fmt"
"os"
)
func main() {
file1, err1 := os.Open("golang_base_17/day09接口和错误/data.txt")
fmt.Println("文件:data.txt", file1.Name(), err1)
file2, err2 := os.Open("golang_base_17/day09接口和错误/data1.txt")
if err2 != nil {
fmt.Println("解决错误::", err2)
} else {
fmt.Println("文件:data1.txt", file2.Name(), err1)
}
}
错误包errors的使用
- 错误errors三种使用方式
- errors.New("") 定义简单字符串错误
- fmt.Errorf("") 格式化输出错误
- 使用断言 t.(*T类型) 输出错误信息
package main
import (
"errors"
"fmt"
"net"
)
func main() {
age := -100
ageErr := checkAge(age)
fmt.Printf("%T\n", ageErr)
fmt.Printf("%v\n", ageErr)
fmtErr01 := fmt.Errorf("网络错误信息:%d\n", 500)
fmtErr02 := fmt.Errorf("参数误信息:%d", 400)
fmt.Printf("%T\n", fmtErr01)
fmt.Printf("%v\n", fmtErr01)
if fmtErr02 != nil {
fmt.Printf("fmtErr02:%T\n", fmtErr02)
fmt.Printf("fmtErr02:%v\n", fmtErr02)
}
address, err := net.LookupHost("www.baidu122.com")
fmt.Println(address, err)
netErr, ok := err.(*net.DNSError)
fmt.Printf("netErr 断言结果的错误类型:%T\n", netErr)
fmt.Printf("ok 断言结果的错误类型:%T\n", ok)
if ok {
if netErr.Temporary() {
fmt.Println("临时错误...")
} else if netErr.Timeout() {
fmt.Println("网络超时错误...")
} else {
fmt.Println("未知错误...")
}
}
}
func checkAge(age int) error {
if age < 0 {
return errors.New("年龄小于0")
} else if age > 100 {
return errors.New("年龄大于100")
} else {
fmt.Println("年龄正常:", age)
}
return nil
}
自定义错误
- 自定义错误结构体
- 实现自定结构体的Error()错误方法
- 编写函数处理业务逻辑,并且包含自定义错误处理
package main
import "fmt"
type MyHttpStructError struct {
statusCode int
message string
data interface{}
}
func (mys MyHttpStructError) Error() string {
return fmt.Sprintf("【MyHttpStruct 错误】。状态码:%d,错误信息:%s,数据:%v", mys.statusCode, mys.message, mys.data)
}
func (mys MyHttpStructError) pprint() bool {
switch mys.statusCode {
case 400:
return true
case 403:
return true
case 500:
return true
case 600:
return false
default:
return false
}
}
func myView(code int) (string, error) {
if code == 600 {
return "访问失败", &MyHttpStructError{statusCode: 600, message: "未知错误"}
}
return "访问成功", nil
}
func main() {
res, err := myView(600)
fmt.Println("【基础错误信息】:", res, err)
if err != nil {
myErrFunc, ok := err.(*MyHttpStructError)
if ok {
fmt.Println(myErrFunc.pprint())
if !myErrFunc.pprint() {
fmt.Println("【自定义错误:pprint】", "条件成立", "执行 pprint 函数检查后的错误逻辑")
} else {
fmt.Println("【自定义错误:pprint】", "条件不成立", "不检查")
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2019-07-02 Python进阶(十二)----re模块