Go 中的面向对象编程——使用“new”关键字还是不使用?

好吧,我至少可以告诉你你在做什么。bindQuery需要一个指针。它更改存储在地址中的值。


你基本上做的是这样的:


package main


import "fmt"


func main() {

    var q int

    myInts := make([]*int, 0, 5)

    for i := 0; i < 5; i++ {

        q = i

        fmt.Printf("%d ", q)

        myInts = append(myInts, &q)

    }

    fmt.Printf("\n")

    for _, value := range myInts {

        fmt.Printf("%d ", *value)

    }

    fmt.Printf("\n")

    fmt.Println(myInts)

}

正如您可能猜到的那样,它为您提供了以下信息:


0 1 2 3 4 

4 4 4 4 4 

[0x104382e0 0x104382e0 0x104382e0 0x104382e0 0x104382e0]

事情变得有点混乱reflect。您可以将您的类型作为接口,但仅此而已(除非您想使用unsafe)。简单来说,接口包含一个指向底层原始类型(以及其他一些东西)的指针。所以在你的函数中你传递了一个指针(和其他一些东西)。然后你要附加指针。只是具体化并键入 switch 您的界面可能会很好。我假设你知道它可能是什么类型。在这种情况下,您必须按照以下方式进行操作:


package main


import (

    "fmt"

    "reflect"

)


type foo struct {

    fooval string

}


type bar struct {

    barval string

}


func main() {

    f1 := foo{"hi"}

    f2 := &foo{"hi"}

    b1 := bar{"bye"}

    b2 := &bar{"bye"}


    doSomething(f1)

    doSomething(f2)

    doSomething(b1)

    doSomething(b2)


}


func doSomething(i interface{}) {

    n := reflect.TypeOf(i)

    // get a new one

    newn := reflect.New(n).Interface()

    // find out what we got and handle each case

    switch t := newn.(type) {

    case **foo:

        *t = &foo{"hi!"}

        fmt.Printf("It was a **foo, here is the address %p and here is the value %v\n", *t, **t)

    case **bar:

        *t = &bar{"bye :("}

        fmt.Printf("It was a **bar, here is the address %p and here is the value %v\n", *t, **t)

    case *foo:

        t = &foo{"hey!"}

        fmt.Printf("It was a *foo, here is the address %p and here is the value %v\n", t, *t)

    case *bar:

        t = &bar{"ahh!"}

        fmt.Printf("It was a *bar, here is the address %p and here is the value %v\n", t, *t)

    default:

        panic("AHHHH")

    }

}

您也可以继续value = reflect.New(query.structType).Interface()在循环内部调用,每次都会为您提供新的接口。每次追加后重新分配值。上次通过循环会使一个额外的虽然..


神不在的星期二
浏览 155回答 1
1回答

慕侠2389804

不想NewThing给ThingFactory。不要创建NewThing函数,除非你有复杂的初始化,或者你故意不导出结构的一部分。选择性地只设置结构的一部分并不复杂,可以通过使用标签来完成。复杂的是“槽 Q 的值取决于槽 Zorb 的值”。未导出的结构字段对于信息隐藏很有用,但应谨慎使用。Go 是垃圾收集的,任何未被引用的数据都有资格被收集。开始时不用担心它,然后确保清除对不再感兴趣的数据的任何引用,以避免意外活跃(“意外活跃”本质上是“内存泄漏”的 GC 等价物”)。如果您希望经常打印数据结构,请考虑String为它们创建一个方法(这与您所做的打印并不完全对应,但通常可能对向量更有用):func (v Vector) String() string {&nbsp; return fmt.Sprintf("V<%d, %d, %d>", v.x v.y, v.z);}除非“vect”对您来说真的很重要,否则更喜欢“v”或“vector”作为名称。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go