繁体   English   中英

动态类型断言Golang

[英]Dynamic Type Assertion Golang

我正在尝试将接口动态地转换回其原始结构,但在转换后访问结构的属性时遇到问题。

以下面的代码为例。

package main

import (
    "fmt"
    "log"
)

type struct1 struct {
    A string
    B string
}

type struct2 struct {
    A string
    C string
}

type struct3 struct {
    A string
    D string
}

func main() {
    s1 := struct1{}
    s1.A = "A"
    structTest(s1)

    s2 := struct2{}
    s2.A = "A"
    structTest(s2)

    s3 := struct3{}
    s3.A = "A"
    structTest(s3)
}

func structTest(val interface{}) {
    var typedVal interface{}

    switch v := val.(type) {
    case struct1:
        fmt.Println("val is struct1")
    case struct2:
        fmt.Println("val is struct2")
    case struct3:
        fmt.Println("val is struct3")
    default:
        log.Panic("not sure what val is.")
    }

    fmt.Println(typedVal.A)
}

我希望能够将3种已知结构类型之一传递给我的函数。 然后找出传入的结构类型以对它进行断言。 最后,我希望能够访问类似属性。

基本上,我想在我的结构中拥有一些基本的继承,但是到目前为止,似乎不可能随时进行。 我看到一些文章提到使用接口继承,但是我的结构没有方法,所以我不确定如何使用接口。

这样的事情可能发生吗?

我希望能够将3种已知结构类型之一传递给我的函数。 然后找出传入的结构类型以对它进行断言。 最后,我希望能够访问类似属性。

您可以使用类型断言来做到这一点。 基本思想是,在任何情况下,类型开关都只需要使用类型断言来获取对应类型的具体实例,然后就可以调用所需的任何属性。

看下面的例子

package main

import (
    "fmt"
)

type test1 struct {
    A, B string
}

type test2 struct {
    A, C string
}

func testType(val interface{}) {
    switch val.(type) {
    case test1:
        t := val.(test1)
        fmt.Println(t.B)
        break
    case test2:
        t := val.(test2)
        fmt.Println(t.C)
        break
    }
}

func main() {
    t1, t2 := test1{B: "hello"}, test2{C: "world"}
    testType(t1)
    testType(t2)
}

操场

代码中的函数structTest(val interface {})似乎是松散键入的。 您将其传递为无类型参数,并期望它满足某些条件(将具有字段A),在任何类型的语言中它看起来都很奇怪。

在我看来,使用接口,这种多态性可以表达为

package main

import (
    "fmt"
    "log"
)

type A string
type HasA interface {
    PrintA()
}

func (a A) PrintA() { fmt.Println(a) }

type struct1 struct {
    A
    B string
}

type struct2 struct {
    A
    C string
}

type struct3 struct {
    A
    D string
}

func main() {
    s1 := struct1{}
    s1.A = "A"
    structTest(s1)

    s2 := struct2{}
    s2.A = "A"
    structTest(s2)

    s3 := struct3{}
    s3.A = "A"
    structTest(s3)
}

func structTest(val HasA) {

    switch val.(type) {
    case struct1:
        fmt.Println("val is struct1")
    case struct2:
        fmt.Println("val is struct2")
    case struct3:
        fmt.Println("val is struct3")
    default:
        log.Panic("not sure what val is.")
    }

    val.PrintA()
}

操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM