使用接口常见的错误: 数据类型的传递问题
package main
import (
"fmt"
)
func PrintAll(vals []interface{}) {
for _, val := range vals {
fmt.Println(val)
}
}
func main() {
names := []string{"stanley", "david", "oscar"}
PrintAll(names)
}
运行这段代码你会得到如下错误:cannot use names (type []string) as type []interface {} in argument to PrintAll。如果想使其正常工作, 我们必须将 []string 转为 []interface{}:
package main
import (
"fmt"
)
func PrintAll(vals []interface{}) {
for _, val := range vals {
fmt.Println(val)
}
}
func main() {
names := []string{"stanley", "david", "oscar"}
// []string 转为 []interface{}:
vals := make([]interface{}, len(names))
for i, v := range names {
vals[i] = v
}
PrintAll(vals)
}
很丑陋, 但是生活就是这样, 没有完美的事情。(事实上, 这种情况不会经常发生, 因为 []interface{} 并没有像你想象的那样有用)
常见的错误: 定义的接口必须实现
package main //必须有个main包
import (
"fmt"
)
type Printer interface { //接口类型
Print() // 定义打印的方法
Composition() // 定义排版的方法
}
type user struct {
name string
age byte
}
func (u user) Print() {
fmt.Printf("%+v\n", u) //%v 基本格式的值。当输出结构体时,扩展标志(%+v)添加成员的名字。
}
func main() {
var u user
u.name = "Tom"
u.age = 29
// 探讨 这里 u (数据类型 user) 为何能传递给 变量 P (数据类型 Printer) ?
// 原因在于: u(数据类型 user) 已经实现了 p (数据类型 Printer) 接口中定义的方法
var p Printer = u //把对象赋值给接口
p.Print() //{name:Tom age:29}
var q Printer = user{"mary", 20}
q.Print() //{name:mary age:20}
}
/*
接口中定义的方法 Composition() 没有实现, 所报的错误
# command-line-arguments
.\demo42.go:25:6: cannot use u (type user) as type Printer in assignment:
user does not implement Printer (missing Composition method)
.\demo42.go:28:6: cannot use user{...} (type user) as type Printer in assignment:
user does not implement Printer (missing Composition method)
*/
正确的代码:
package main //必须有个main包
import (
"fmt"
)
type Printer interface { //接口类型
Print() // 定义打印的方法
Composition() // 定义排版的方法
}
type user struct {
name string
age byte
}
func (u user) Print() {
fmt.Printf("%+v\n", u) //%v 基本格式的值。当输出结构体时,扩展标志(%+v)添加成员的名字。
}
func (u user) Composition() {}
func main() {
var u user
u.name = "Tom"
u.age = 29
// 探讨 这里 u (数据类型 user) 为何能传递给 变量 P (数据类型 Printer) ?
// 原因在于: u(数据类型 user) 已经实现了 p (数据类型 Printer) 接口中定义的方法
var p Printer = u //把对象赋值给接口
p.Print() //{name:Tom age:29}
var q Printer = user{"mary", 20}
q.Print() //{name:mary age:20}
}