【问题标题】:Golang: Type Assertion Error issueGolang:类型断言错误问题
【发布时间】:2016-09-22 21:26:44
【问题描述】:

我被下面代码 sn-p 中的类型断言相关错误所困扰。我不确定我错过了什么。我在以下地方进行类型断言 itr = itr.(*DbIterator).Iterator 和 key := itr.Key().(*Key).Slice 和 value := itr.Value().(*Value)。片。我想知道是否有更好的方法来做到这一点,而无需代码库中到处都有类型断言或更好的设计模式来处理这种情况。代码 sn-p 是更大代码库的一部分。我已经为这个问题提取了最相关的部分。非常感谢这方面的任何帮助。

package rocksdb

import (
    "github.com/tecbot/gorocksdb"
)

func (s *RocksDB) GetCFIterator(cfHandler *gorocksdb.ColumnFamilyHandle) db.Iterator {
    opt := gorocksdb.NewDefaultReadOptions()
    opt.SetFillCache(true)
    defer opt.Destroy()
    return &DbIterator{s.DB.NewIteratorCF(opt, cfHandler)}
}

type DbIterator struct {
    *gorocksdb.Iterator
}

type Key struct {
    *gorocksdb.Slice
}

type Value struct {
    *gorocksdb.Slice
}

func (iterator *DbIterator) Key() db.Keyer {
    return &Key{iterator.Iterator.Key()}
}

func (iterator *DbIterator) Value() db.Valuer {
    return &Value{iterator.Iterator.Value()}
}

type RocksDB struct {
    DB *gorocksdb.DB
}

我有一个交互界面

package db

import (
    "bytes"
    "testing"
)

type Iterator interface {
    Valid() bool
    Next()
    Close()
    SeekToFirst()
    SeekToLast()
    Seek(key []byte)
    Key() Keyer
    Value() Valuer
}

type Keyer interface {
}

type Valuer interface {
}

func testIterator(t *testing.T, itr db.Iterator, expectedValues map[string][]byte) {
    itrResults := make(map[string][]byte)
    itr = itr.(*DbIterator).Iterator //Line 270 which the error throws
    itr.SeekToFirst()
    for ; itr.Valid(); itr.Next() {
        key := itr.Key().(*Key).Slice
        value := itr.Value().(*Value).Slice
        k := makeCopy(key.Data())
        v := makeCopy(value.Data())
        itrResults[string(k)] = v
    }
    if len(itrResults) != len(expectedValues) {
        t.Fatalf("Expected [%d] results from iterator, found [%d]", len(expectedValues), len(itrResults))
    }
    for k, v := range expectedValues {
        if !bytes.Equal(itrResults[k], v) {
            t.Fatalf("Wrong value for key [%s]. Expected [%s], found [%s]", k, itrResults[k], v)
        }
    }
}

错误信息

github.com/hyperledger/fabric/core/db/rocksdb
core/db/rocksdb/rocksdb_test.go:270: cannot use itr.(*DbIterator).Iterator (type *gorocksdb.Iterator) as type db.Iterator in assignment:
*gorocksdb.Iterator does not implement db.Iterator (wrong type for Key method)
have Key() *gorocksdb.Slice
want Key() db.Keyer

【问题讨论】:

    标签: go types


    【解决方案1】:

    问题不在于类型断言,因为您正在使用的实例没有实现该接口,所以无论如何您都会在那里中断。话虽如此,您可以通过这样做来优雅地处理它;

     itr, ok = itr.(*DbIterator)
     if !ok {
         //try to recover
     }
    

    但是,是的,就像我说的那样,当您访问该代码时,itr 的类型不是代码所期望的,因此它不会以期望的结果结束,您必须进行一些恢复/错误处理在这里让它更好地工作或弄清楚你是如何得到错误的类型的。

    【讨论】:

    • 谢谢!!!删除 itr.(*DbIterator).Iterator 中的迭代器解决了这个问题!但仍然试图理解为什么这首先会导致问题......
    • @Nik itr 的类型是 *gorocksdb.Iterator 但断言是针对 *DbIterator 的,因此除非您调用将状态作为布尔值返回的版本,否则它会引发错误。如果您不确定该类型,您想使用返回 2 args 的版本来检查它。如果您知道类型,则基本上可以使用原始样本中的版本,就像演员一样。但是,如果类型不是您断言的类型,您会感到恐慌,这与 invalidcastexception 或 C#/C 世界中的类似内容基本相同。
    • 感谢埃文的解释!我刚刚意识到我首先不需要类型断言,因为它确实无法断言和恐慌......正如你指出的那样,我试图弄清楚错误类型是如何被传递下来的
    猜你喜欢
    • 2014-01-22
    • 1970-01-01
    • 2016-10-03
    • 2019-01-01
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 2014-01-08
    相关资源
    最近更新 更多