为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
素胚勾勒不出你 2022-08-24 16:08:22
我有下面的代码,它的目的只是创建结构对象的映射,并调用一个复制映射然后打印它的函数。当我删除所有内容中的行时,一切都有效(除了id,它对于每次运行都是常数,正如预期的那样),否则它只会将最后一个元素添加到映射中。为什么会发生这种情况?ComicBookrand.Seed()SetId()comicBook.gopackage srcimport (    "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.gopackage mainimport (    "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
查看完整描述

2 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

你使用不安全的方法来生成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但是。你没有读到这些操作之间的时间可能太短,因此,密钥本身与我的测试相同:


1257894000000000000

0

1257894000000000000

0

1257894000000000000

0

使用单个变量来保存你的种子,就像这样:(我使用全局变量,但你可以在 ComicBook 结构中添加种子 var)


import (

    "math/rand"

    "fmt"

)

var seed int

...


func (book *ComicBook) SetId()  int{

    seed += 1

    rand.Seed(int64(seed))

    id := rand.Intn(100)

和测试:


1

81

2

86

3

8

在你的代码中,任何地图元素都有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:  false

Id:  8 , Name:   , Publisher:   , Sold:  false

Id:  81 , Name:   , Publisher:   , Sold:  false

https://play.golang.org/p/Z9_tFNdlBqp


并且,如果将变量用于 id,则无需使用 rand:


func (book *ComicBook) SetId()  int{

    seed += 1

    book.id = seed

    fmt.Println(book.id)

    return seed

}


查看完整回答
反对 回复 2022-08-24
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

首先,您只能使用一次(例如 in 或 function)。rand.Seed()maininit

其次,可能会返回相同的值两次(因为它是随机的,而不是唯一的),这意味着先前的map记录将被覆盖。rand.Intn()

你的问题的解决方案将是更改函数,它返回随机数,函数,返回一些标识符(如UUID)。


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信