簡體   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