2016-09-22 2 views
0

Ich bin durch die Art Assertion Fehler im unteren Teil des Code-Snippet gebissen. Ich bin mir nicht sicher, was ich vermisse. Ich mache Typ Assertions in den folgenden Orten itr = itr. (* DbIterator) .Iterator und Schlüssel: = itr.Key(). (* Key) .Slice und Wert: = itr.Value(). (* Wert). Scheibe. Ich frage mich, ob es einen besseren Weg gibt, dies zu tun, ohne Typ-Assertions überall in der Code-Basis oder bessere Design-Muster, um mit dieser Art von Szenario umzugehen. Das Code-Snippet ist Teil einer größeren Codebasis. Ich habe die relevantesten Bits für diese Frage gezogen. Jede Hilfe in dieser Hinsicht wird sehr geschätzt.Golang: Typ Assertion Fehler Ausgabe

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 
} 

Ich habe eine interator Schnittstelle

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) 
     } 
    } 
} 

Fehlermeldung

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 

Antwort

1

Das Problem ist nicht der Typ behauptet, Sie sind gonna break es egal, weil die Instanz du bist Das Arbeiten mit implementiert diese Schnittstelle nicht. Wenn du das sagst, kannst du damit elegant umgehen;

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

Aber ja, wie ich schon sagte, wenn Sie zu diesem Code erhalten die Art der itr ist nicht das, was der Code erwartet, also ist es nicht mit dem gewünschten Ergebnis zu Ende gehen, werden Sie eine gewisse Erholung zu tun haben/Fehlerbehandlung hier, damit es besser funktioniert oder herauszufinden, wie Sie den falschen Typ bekommen, der dort ursprünglich weitergegeben wurde.

+0

Danke !!! Entfernen des Iterators in itr. (* DbIterator) .Iterator behoben das Problem! Aber immer noch versuchen zu verstehen, warum das das Problem an erster Stelle verursacht hat ... – Nik

+1

@Nik 'itr's Typ ist' * gorocksdb.Iterator', aber die Assert ist für einen '* DbIterator', so dass es einen Fehler gibt, es sei denn Sie rufen diese Version auf, die den Status als Bool zurückgibt. Wenn Sie sich bei diesem Typ unsicher sind, möchten Sie die Version verwenden, die 2 Argumente zurückgibt, um sie zu überprüfen. Wenn Sie den Typ kennen, können Sie die Version, die Sie in der ursprünglichen Probe hatten, grundsätzlich wie eine Besetzung verwenden. Aber wenn der Typ nicht das ist, was Sie behaupten, erhalten Sie eine Panik, die im Grunde genommen die gleiche ist wie eine "Ungültigkassexzeption" oder etwas in dieser Richtung in der C#/C-Welt. – evanmcdonnal

+0

Danke evan für die Erklärung! Ich habe gerade gemerkt, dass ich die Typ-Assertion überhaupt nicht brauche, weil sie nicht behauptet und in Panik versetzt wird. Wie du schon gesagt hast, versuche ich herauszufinden, wie ein falscher Typ überhaupt weitergegeben wird – Nik