与私有接口比较 [英] Comparing with a private interface
问题描述
我有两个对象。 key1
的类型为 * rsa.PublicKey
。 key2
是 * ssh.PublicKey
类型,它是隐藏 * ssh.rsaPublicKey
对象。 ssh.rsaPublicKey
定义为:
I have two objects. key1
is of type *rsa.PublicKey
. key2
is of type *ssh.PublicKey
which is an interface hiding a *ssh.rsaPublicKey
object. ssh.rsaPublicKey
is defined as:
type ssh.rsaPublicKey rsa.PublicKey
它还有一些额外的方法。但是,由于该类是未导出,我不能将任一键转换为 ssh.rsaPublicKey
,我不能转换 key2
到
rsa.PublicKey
,因为它不实现 ssh.PublicKey
,我可以'从 key2
访问 N
或 e
不应该知道我有一个 rsaPublicKey
对象。
And it has a few extra methods. However, I can't cast either key to an ssh.rsaPublicKey
since that class is "not exported", I can't cast key2
to an rsa.PublicKey
since that doesn't implement ssh.PublicKey
, and I can't access the N
or e
from key2
because I am not supposed to know I have an rsaPublicKey
object.
我应该如何比较 key1
和 key2
是否相同?
How am I supposed to compare that key1
and key2
are the same key?
推荐答案
如前所述,您无法使用类型声明,因为您无法参考到未导出的类型 ssh.rsaPublicKey
。
As you mentioned, you can't use type assertion because you can't refer to the unexported type ssh.rsaPublicKey
.
您可以使用 反映
包。
What you want is possible with using the reflect
package.
由于 rsa.PublicKey
是 ssh.rsaPublicKey
的底层类型,指向包装在 key2
中的值可以转换为 rsa.PublicKey
。获取 reflect.Value
后您的 key2
,使用指向 .Elemrel =nofollow> Value.Elem()
。此值可转换为 rsa.PublicKey
类型的值。您可以使用 Value.Convert()
到动态,在运行时将其转换为 rsa.PublicKey
。获得后,您可以使用 reflect.DeepEquals()
进行比较,或手动比较。
Since rsa.PublicKey
is the underlying type of ssh.rsaPublicKey
, the pointed value wrapped in key2
can be converted to rsa.PublicKey
. Once you obtain reflect.Value
of your key2
, "navigate" to the pointed value using Value.Elem()
. This value is convertible to a value of type rsa.PublicKey
. You may use the Value.Convert()
to "dynamically", at runtime convert it to rsa.PublicKey
. Once you have it, you can use reflect.DeepEquals()
to do the comparison, or compare it manually.
这是它的样子:
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
。
Note that when comparing manually, comparing the PublicKey.N
field –which is of type *big.Int
– you need to use the Int.Cmp()
method because comparing pointers compares the memory addresses, not the pointed values. And Int.Cmp()
returns 0
if the 2 values are equal.
这篇关于与私有接口比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!