【问题标题】:Comparing with a private interface与私有接口比较
【发布时间】:2016-08-18 17:49:07
【问题描述】:

我有两个对象。 key1 的类型为 *rsa.PublicKeykey2*ssh.PublicKey 类型,它是一个隐藏 *ssh.rsaPublicKey 对象的接口。 ssh.rsaPublicKey 定义为:

type ssh.rsaPublicKey rsa.PublicKey

它还有一些额外的方法。但是,我不能将任一键转换为ssh.rsaPublicKey,因为该类“未导出”,我不能将key2 转换为rsa.PublicKey,因为它没有实现ssh.PublicKey,我可以'不要从key2 访问Ne,因为我不应该知道我有一个rsaPublicKey 对象。

我应该如何比较 key1key2 是同一个键?

【问题讨论】:

  • 对于陈述者,您对平等的定义是什么?我想有一些方法可以获取数据或进行转换。
  • 我对相等的定义是“模数相同,N”。

标签: go interface comparison


【解决方案1】:

正如你所提到的,你不能使用type assertion,因为你不能引用未导出的类型ssh.rsaPublicKey

使用reflect 包可以实现您想要的。

由于rsa.PublicKeyssh.rsaPublicKey 的基础类型,所以包裹在key2 中的pointed 值可以转换为rsa.PublicKey。一旦你获得了key2 中的reflect.Value,使用Value.Elem()“导航”到pointed 值。此值可转换为 rsa.PublicKey 类型的值。您可以使用Value.Convert() 来“动态地”,在运行时将其转换为rsa.PublicKey。拿到后,可以使用reflect.DeepEquals()进行对比,也可以手动对比。

这就是它的样子:

key1 := &rsa.PublicKey{N: big.NewInt(123), E: 10}
key2, _ := ssh.NewPublicKey(&rsa.PublicKey{N: big.NewInt(123), E: 10})


key2conv := reflect.ValueOf(key2).Elem().
    Convert(reflect.TypeOf(rsa.PublicKey{})).Interface()
// key2conf is an interface{}, wrapping an rsa.PublicKey

// Comparision with DeepEqual
fmt.Println(reflect.DeepEqual(*key1, key2conv))

// Comparing manually:
key22 := key2conv.(rsa.PublicKey)
fmt.Println(key1.N.Cmp(key22.N)) // Int.Cmp() returns 0 if equal
fmt.Println(key1.E == key22.E)

请注意,手动比较时,比较PublicKey.N 字段(类型为*big.Int)需要使用Int.Cmp() 方法,因为比较指针比较的是内存地址,而不是指向的值。如果两个值相等,Int.Cmp() 将返回 0

【讨论】:

    猜你喜欢
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多