go类型转换
数值类型转换
type_name(expression)
var a int = 10
var b float64 = float64(a)
示例:
package main
import "fmt"
func main() {
var sum int = 17
var count int = 5
var mean float32
mean = float32(sum)/float32(count)
fmt.Printf("mean 的值为: %f\n",mean)
}
字符串类型转换
将字符串变量 str 转换为整型变量 num。
注意,strconv.Atoi 函数返回两个值,第一个是转换后的整型值,第二个是可能发生的错误,我们可以使用空白标识符 _ 来忽略这个错误
var str string = "10"
var num int
num, _ = strconv.Atoi(str)
//将字符串转换为浮点数:
num := 123
str := strconv.Itoa(num)
fmt.Printf("整数 %d 转换为字符串为:'%s'\n", num, str)
接口类型转换
类型断言
类型断言用于将接口类型转换为指定类型,其语法为:
value.(type)
或者
value.(T)
其中 value 是接口类型的变量,type 或 T 是要转换成的类型。
如果类型断言成功,它将返回转换后的值和一个布尔值,表示转换是否成功。
package main
import "fmt"
func main() {
var i interface{} = "Hello, World"
str, ok := i.(string)
if ok {
fmt.Printf("'%s' is a string\n", str)
} else {
fmt.Println("conversion failed")
}
}
类型转换
类型转换用于将一个接口类型的值转换为另一个接口类型,类似与java 的强制类型转换。其语法为:
T(value)
空接口类型
在 Go 语言中,interface{}
(空接口)和 Java 的 Object
类似,但它们在类型系统、使用方式和底层实现上有一些重要区别。
interface{}
不是一个基类,而是一个接口,它没有任何方法定义,因此任何类型都自动实现了它。Go 的
interface{}
可以直接存储任意类型,包括值类型(int
、float64
)和引用类型(struct
、map
)。在 Go 语言中,
interface{}
变量存储了 两个部分:动态类型(type):存储该值的实际类型。
动态值(value):存储该值的实际数据。
var any interface{} = "Hello"
fmt.Printf("Type: %T, Value: %v\n", any, any)
输出:Type: string, Value: Hello
总结
接口
接口的特点
隐式实现:
Go 中没有关键字显式声明某个类型实现了某个接口。
只要一个类型实现了接口要求的所有方法,该类型就自动被认为实现了该接口。
接口类型变量:
接口变量可以存储实现该接口的任意值。
接口变量实际上包含了两个部分:
动态类型:存储实际的值类型。
动态值:存储具体的值。
零值接口:
接口的零值是
nil
。一个未初始化的接口变量其值为
nil
,且不包含任何动态类型或值。
package main
import "fmt"
type Speaker interface {
Speak()
}
func main() {
var s Speaker // 此时 s 为 nil
fmt.Println(s) // 输出 <nil>
// s.Speak() // 运行时错误:调用 nil 接口的方法
}
空接口:
定义为
interface{}
,可以表示任何类型。
接口的常见用法
多态:不同类型实现同一接口,实现多态行为。
泛化:使用空接口
interface{}
表示任意类型。解耦:通过接口定义依赖关系,降低模块之间的耦合。允许接口组合
package main
import "fmt"
// 定义接口
type Walker interface {
Walk()
}
type Talker interface {
Talk()
}
// 组合接口
type Human interface {
Walker
Talker
}
// 结构体实现
type Person struct{}
func (p Person) Walk() {
fmt.Println("Walking")
}
func (p Person) Talk() {
fmt.Println("Talking")
}
func main() {
var h Human = Person{}
h.Walk()
h.Talk()
}
错误处理
1. Go 和 Java 错误处理对比
2. 定义
error
是一个接口类型,定义如下:
任何实现 Error()
方法的类型,都可以作为 error
类型返回。
type error interface {
Error() string
}
3. 自定义错误
package main
import (
"errors"
"fmt"
)
// 定义自定义错误类型
type MyError struct {
Code int
Msg string
}
func (e *MyError) Error() string {
return fmt.Sprintf("Code: %d, Msg: %s", e.Code, e.Msg)
}
// 可能返回自定义错误
func doSomething(fail bool) error {
if fail {
return &MyError{Code: 400, Msg: "Something went wrong"}
}
return nil
}
func main() {
err := doSomething(true)
if err != nil {
fmt.Println("Error:", err)
}
}
4. panic 和 recover
(类似 Java 的 RuntimeException)
Go 不推荐使用 panic
,但在 严重错误(如数组越界)时可以使用 panic
+ recover
处理异常。
g
🔹 解释
panic("message")
触发异常。recover()
捕获 panic,防止程序崩溃。
5. errors.Is 和 errors.As
errors.Is
检查某个错误是否是特定错误或由该错误包装而成。
package main
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("not found")
func findItem(id int) error {
return fmt.Errorf("database error: %w", ErrNotFound)
}
func main() {
err := findItem(1)
if errors.Is(err, ErrNotFound) {
fmt.Println("Item not found")
} else {
fmt.Println("Other error:", err)
}
}
errors.As
将错误转换为特定类型以便进一步处理。