使用兰特填充结构图。Seed() 仅插入最后一个对象

我有下面的代码,它的目的只是创建结构对象的映射,并调用一个复制映射然后打印它的函数。当我删除所有内容中的行时,一切都有效(除了id,它对于每次运行都是常数,正如预期的那样),否则它只会将最后一个元素添加到映射中。为什么会发生这种情况?ComicBookrand.Seed()SetId()


comicBook.go


package src


import (

    "math/rand"

    "sync"

    "time"

)


type ComicBook struct {

    id        int

    name      string

    publisher string

    sold      bool

}


type Book interface {

    GetId() int

    SetId() int

    GetName() string

    GetPublisher() string

    GetIsSold() bool

    New(name string, author string) ComicBook

}


func (book ComicBook) SetId()  int{

        rand.Seed(time.Now().UTC().UnixNano())

        id := rand.Intn(100)

        book.id = id

    return id

}


func (book ComicBook) New(name string, author string) ComicBook {

    id := book.SetId()

    b := ComicBook{id, name, author, false}

    return b

}


func (book ComicBook) GetId() int{

    return book.id

}


func (book ComicBook) GetName() string{

    return book.name

}


func (book ComicBook) GetPublisher() string{

    return book.publisher

}


func (book ComicBook) GetIsSold() bool{

    return book.sold

}

main.go


package main


import (

    "awesomeProject1/src"

    "fmt"

)


var (

    ComicBook src.ComicBook

)


func copyMap(m map[int]src.ComicBook) map[int]src.ComicBook {

    newMap := make(map[int]src.ComicBook)

    for k, v := range m {

        newMap[k] = v

    }

    return newMap

}


func main()  {

    b := src.ComicBook{}.New("A", "B")

    bTwo := src.ComicBook{}.New("The Dark Knight Returns", "DC Comics")

    bThree := src.ComicBook{}.New("Watchmen", "DC Comics")

    m := map[int]src.ComicBook{

        b.GetId():    b,

        bTwo.GetId(): bTwo,

        bThree.GetId(): bThree,

    }

    newMap := copyMap(m)

    for k, v := range newMap {

        fmt.Println("Id: ", k, ", Name: ", v.GetName(), ", Publisher: ", v.GetPublisher(), ", Sold: ", v.GetIsSold())

    }

}


输出:


Id:  91 , Name:  Watchmen , Publisher:  DC Comics , Sold:  false


素胚勾勒不出你
浏览 74回答 2
2回答

茅侃侃

你使用不安全的方法来生成id.我测试你的代码:https://play.golang.org/p/S0_CWMqNH2-rand.Seed(time.Now().UTC().UnixNano())fmt.Println(time.Now().UTC().UnixNano())id := rand.Intn(100)fmt.Println(id)这未保存。你可以认为,相同的键可以是1/100但是。你没有读到这些操作之间的时间可能太短,因此,密钥本身与我的测试相同:125789400000000000001257894000000000000012578940000000000000使用单个变量来保存你的种子,就像这样:(我使用全局变量,但你可以在 ComicBook 结构中添加种子 var)import (    "math/rand"    "fmt")var seed int...func (book *ComicBook) SetId()  int{    seed += 1    rand.Seed(int64(seed))    id := rand.Intn(100)和测试:18128638在你的代码中,任何地图元素都有0个键并相互重写,但现在:map[8:{8   false} 81:{81   false} 86:{86   false}]map[8:{8   false} 81:{81   false} 86:{86   false}]Id:  86 , Name:   , Publisher:   , Sold:  falseId:  8 , Name:   , Publisher:   , Sold:  falseId:  81 , Name:   , Publisher:   , Sold:  falsehttps://play.golang.org/p/Z9_tFNdlBqp并且,如果将变量用于 id,则无需使用 rand:func (book *ComicBook) SetId()  int{    seed += 1    book.id = seed    fmt.Println(book.id)    return seed}

犯罪嫌疑人X

首先,您只能使用一次(例如 in 或 function)。rand.Seed()maininit其次,可能会返回相同的值两次(因为它是随机的,而不是唯一的),这意味着先前的map记录将被覆盖。rand.Intn()你的问题的解决方案将是更改函数,它返回随机数,函数,返回一些标识符(如UUID)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go