我正在学习 Go 语言,想知道是否有一种方法可以做到这一点:
type Foo struct {
...
}
type Bar struct {
Foo
...
}
func getFoo() Foo {
return Bar{...}
}
在面向对象的语言中,这样的代码应该可以正常工作,但在Go语言中,它会抛出一个错误,指出getFoo()
必须返回类Foo的实例。是否有一种类似于我所描述的在Go中进行多态性操作的方式?
我正在学习 Go 语言,想知道是否有一种方法可以做到这一点:
type Foo struct {
...
}
type Bar struct {
Foo
...
}
func getFoo() Foo {
return Bar{...}
}
在面向对象的语言中,这样的代码应该可以正常工作,但在Go语言中,它会抛出一个错误,指出getFoo()
必须返回类Foo的实例。Go并不是一个典型的面向对象语言。此外,每种语言都有其自己的处理方式。您可以使用接口和组合来实现所需的功能,如下所示:
package main
import "fmt"
type Foo interface {
printFoo()
}
type FooImpl struct {
}
type Bar struct {
FooImpl
}
type Bar2 struct {
FooImpl
}
func (f FooImpl)printFoo(){
fmt.Println("Print Foo Impl")
}
func getFoo() Foo {
return Bar{}
}
func main() {
fmt.Println("Hello, playground")
b := getFoo()
b.printFoo()
}
Bar2
? - Jeff Widmantype Being interface {
somemethod()
}
type Foo struct {}
type Bar struct {
Foo
}
type Baz struct {
Foo
}
// `Bar` and `Baz` implement `Being`
func (b *Bar) somemethod() {}
func (b *Baz) somemethod() {}
func getAnyFoo(b *Being) Foo {
return b.Foo
}
type Foo struct {}
type Bar struct {
Foo
}
// Get anything and extract its `Foo` if anything is a Bar
func getAnyFoo(i interface{}) Foo {
// Normally this would need a type switch to check the type
mybar := i.(Bar)
return mybar.Foo
}
你可以这样使用它。如果你给 print 函数一个 person 或 secret Agent,它会理解它来自于人类界面并在其中运行该函数。
包 main
import "fmt"
type person struct {
firstName string
lastName string
age int
}
type secretAgent struct {
person
ltk bool
}
type human interface {
info() string
}
func (p person) info() string {
return fmt.Sprint("Name:", p.firstName, " Surname:", p.lastName, " Age:", p.age)
}
func (s secretAgent) info() string {
return fmt.Sprint("Name:", s.firstName, " Surname:", s.lastName, " Age:", s.age, " Ltk:", s.ltk)
}
func print(h human) {
switch h.(type) {
case person:
fmt.Println("person struct:")
fmt.Println(h.info())
case secretAgent:
fmt.Println("secretAgent struct:")
fmt.Println(h.info())
}
}
func main() {
p := person{
firstName: "Khanbala",
lastName: "Reshidov",
age: 22,
}
s := secretAgent{
person: p,
ltk: true,
}
//info Method
fmt.Println(p.info())
fmt.Println(s.info())
//polymorphism
print(p)
print(s)
//type
fmt.Printf("%T\n", p)
fmt.Printf("%T\n", s)
}
如果您知道要使用的类型,可以将它们放入数组列表中以实现一种多态实例化:
package main
import (
"fmt"
"encoding/json"
)
type Hans struct{
Miau string
}
type Keule struct {
Wuff string
}
func (K Keule)ppp() {
fmt.Printf(K.Wuff)
}
func (K Hans)ppp() {
fmt.Printf(K.Miau)
}
func (K Keule)TypeInfo() int {
return 0
}
func (K Hans)TypeInfo() int {
return 1
}
type Mega interface {
ppp()
TypeInfo() int
}
var j_a = `{
"Kein_Alter": "nix",
"Miau": "lala",
"class": 0
}`
var j_b = `{
"Alter": "nix",
"Wuff": "lolo",
"Class": 1
}`
type Class struct {
Class int
}
func (K *Class)ppp() {
fmt.Printf("%d", K.Class)
}
func Unmarshal_K(b []byte) (Mega, error) {
var k Keule
err := json.Unmarshal([]byte(j_a), &k)
return k, err
}
func Unmarshal_H(b []byte) (Mega, error) {
var k Hans
err := json.Unmarshal([]byte(j_a), &k)
return k, err
}
var UList = []func(b []byte) (Mega, error) {Unmarshal_H, Unmarshal_K}
func main() {
var mv Class
err := json.Unmarshal([]byte(j_a), &mv)
if err != nil {
panic(err)
}
hiho, err := UList[mv.Class]([]byte(j_a))
if err != nil {
panic(err)
}
hiho.ppp()
}
package main
import "fmt"
// declare interface type
type Dog interface {
Bark()
}
type Dalmatian struct {
DogType string
}
type Labrador struct {
DogType string
}
// implement the interface for both structs
func (d Dalmatian) Bark() {
fmt.Println("Dalmatian barking!!")
}
func (l Labrador) Bark() {
fmt.Println("Labrador barking!!")
}
// takes a Dog interface as a parameter
func MakeDogBark(d Dog) {
d.Bark()
}
func main() {
// create two instances of different structs that implement the Dog interface
d := Dalmatian{"Jack"}
l := Labrador{"Max"}
// pass them to the function that accepts the Dog interface
MakeDogBark(d) // Dalmatian barking!!
MakeDogBark(l) // Labrador barking!!
}