2016-09-22 3 views
0

코드 단편의 아래에있는 어설 션 관련 오류로 물린 것으로 나타납니다. 나는 내가 무엇을 놓치고 있는지 확신하지 못한다. iter = itr. (* DbIterator) .Iterator 및 key : = itr.Key(). (* Key) .Slice 및 value : = itr.Value(). (* 값) 다음 위치에 형식 어설 션을 수행하고 있습니다. 일부분. 이런 종류의 시나리오를 처리하기 위해 코드 기반 또는 더 나은 디자인 패턴에서 유형 어설 션없이 모든 작업을 수행하는 더 좋은 방법이 있는지 궁금합니다. 코드 스 니펫은 더 큰 코드 기반의 일부입니다. 이 질문에 가장 관련있는 부분을 찾아 냈습니다. 이와 관련하여 도움이된다면 많은 도움이됩니다. 인스턴스 당신이이기 때문에Golang : 형식 어설 션 오류 이슈

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 
} 

내가 상관없이 거기에 interator 인터페이스를

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 

답변

1
문제는 유형이 주장되지

, 당신은거야 휴식을 함께 작업하면 해당 인터페이스가 구현되지 않습니다. 그것은 당신이하기에 의하여 우아하게 이것을 취급 할 수있다 말했다.

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

하지만 그래, 난 당신이 그 코드에 도착하면 itr의 유형, 당신은/어떤 복구를해야 할 것이다 어떤 코드가 원하는 결과로 끝나지 않을거야 너무 기대하지 말했듯 오류 처리를 통해 오류가 더 잘 발생하도록하거나 잘못된 유형의 오류가 처음부터 전달되는 방식을 파악할 수 있습니다.

+0

감사합니다. iter.에서 반복자 제거 (* DbIterator) .Iterator가 문제를 해결했습니다! 하지만 그 이유가 처음에 그 문제를 일으키는 이유를 이해하려고 노력 중입니다 ... – Nik

+1

@Nik'itr'의 타입은'* gorocksdb.Iterator'이지만 어설 션은'* DbIterator'를위한 것입니다. 당신은 그 상태를 bool로 반환하는 버전을 호출합니다. 그 타입에 대해 확신이 없다면, 그것을 확인하기 위해 2 args를 리턴하는 버전을 사용하고 싶을 것이다. 유형을 알고 있으면 기본적으로 캐스트와 같은 원본 샘플에 있던 버전을 사용할 수 있습니다. 그러나 타입이 당신이 주장하는 것과 다르다면 당신은 기본적으로 C#/C 세계에서의 그 라인을 따르는'invalidcastexception' 또는 무언가와 같은 공포를 당하게 될 것입니다. – evanmcdonnal

+0

설명을 주셔서 감사합니다! 나는 처음에 타입 어썰트가 필요 없다는 것을 깨달았습니다. 어설 션과 패닉에 실패했기 때문입니다. 당신이 지적했듯이 잘못된 타입이 처음부터 어떻게 전달되었는지를 알아 내려고합니다. – Nik