速戰速決 go https://github.com/webabcd/GoSample
作者 webabcd
速戰速決 go - go 面向對象: 接口(空接口,類型斷言,通過實現內置的 error 接口實現自定義錯誤類型)
示例如下:
oop/interface2.go
// go 面向對象 - 接口(空接口,類型斷言,通過實現內置的 error 接口實現自定義錯誤類型)
package oop
import (
"errors"
"fmt"
)
func Interface2Sample() {
interface2_sample1()
interface2_sample2()
}
func interface2_sample1() {
// 聲明一個空接口類型的變量(類似於 c# 的 object,也就是說空接口可以保存任何類型的值)
var a interface{}
a = 1
fmt.Println(a)
a = "abc"
fmt.Println(a)
var b interface{}
b = "abc"
// 如果兩個空接口保存的值是相等的,則這兩個空接口是相等的
fmt.Println(a == b)
// 如果需要從空接口中取出原類型的值,是不能像下面這樣直接寫的
// var c string = b
// 如果需要從空接口中取出原類型的值,則要使用類型斷言(type assertion),其語法爲 x.(T)
var c string = b.(string)
fmt.Println(c)
// 也可以這麼寫,第一個返回值是轉換後的值,第二個返回值用於表示轉換是否成功
e, f := b.(string)
fmt.Println(e, f) // abc true
// 通過類型斷言判斷接口的原數據類型是什麼
// 注:只能在 switch 中使用 a.(type) 這種寫法
switch a.(type) {
case string:
fmt.Println("a 是 string: " + a.(string)) // 要將空接口轉爲字符串,記得要像這樣 a.(string) 斷言
default:
fmt.Println("不知道 a 是啥類型")
}
// 類似這樣 g := a.(type) 將斷言的結果給 g,可以避免後續使用的時候再斷言
switch g := a.(type) {
case string:
fmt.Println("a 是 string: " + g) // g 就是 a 斷言後的結果,所以不用再對 a 斷言了
default:
fmt.Println("不知道 a 是啥類型")
}
}
// 本例用於演示如何通過實現內置的 error 接口實現自定義錯誤類型
func interface2_sample2() {
// 調用函數,拿到函數返回的自定義 error 類型
_, err := interface2_func1(5)
if err != nil {
fmt.Println(err.Error()) // 錯誤信息:參數不能小於 10
}
// 調用函數,拿到函數返回的內置 error 類型
_, err2 := interface2_func1(100)
if err2 != nil {
fmt.Println(err2.Error()) // 參數不能是 100
}
}
// 這個函數的返回值包含一個 error 接口
func interface2_func1(a int) (int, error) {
if a < 10 {
// 返回自定義 error 類型
return -1, interface2_struct1{"參數不能小於 10"}
} else if a == 100 {
// 返回內置 error 類型
return -1, errors.New("參數不能是 100")
} else {
return a, nil
}
}
// 定義一個結構體
type interface2_struct1 struct {
errorMessage string
}
/*
type error interface {
Error() string
}
*/
// 爲結構體實現 error 接口,error 接口是一個內置接口,其定義就是上面註釋的代碼
func (e interface2_struct1) Error() string {
return "錯誤信息:" + e.errorMessage
}
速戰速決 go https://github.com/webabcd/GoSample
作者 webabcd