2016-10-11 5 views
0

Я пытался создать пользовательский итератор, который возвращает обертку abcContainer над сырым классом данных abcSwift 3 - Последовательность неоднозначной без больше контекста

// raw data class 
class abc { 
    var name : String = ""; 
    init(_ value : String) { 
     name = value; 
    } 
} 

// with container, only "name" is to be visible 
class abcContainer { 
    private var _abc : abc; 
    init(_ obj : abc) { 
     _abc = obj; 
    } 
    // + extra methods here 
    func getName() -> String { 
     return _abc.name 
    } 
} 

Делом было в том, что словарь будет возвращать экземпляры из abcContainer вместо просто простой товар abc класс.

Я хотел бы использовать протокол последовательности, чтобы сделать преобразование автоматически, но я не был в состоянии преобразования [String:abc] в [String:abcContainer] автоматически, как это:

// the iterator is implemented just iterating the inner basic dict 
// but wrapping the result value as abcContainer 
class abcIterator : Sequence, IteratorProtocol { 

    private var __source : [String:abc]?; 
    var index = 0 
    var myIterator : DictionaryIterator<String, abc>; 

    init(_ ctxArray: [String:abc]) { 
     self.__source = ctxArray 
     index = 0; 
     myIterator = (__source?.makeIterator())! 
    } 

    func next() -> abcContainer? { 
     let nextItem = myIterator.next(); 
     if(nextItem != nil) { 
      return abcContainer((nextItem?.value)!); 
     } 
     return nil; 
    } 
} 

// this was supposed to be the wrapper over the collection 
class abcCollection : Sequence { 

    private var __source : [String:abc]?; 

    init(_ list: [String:abc]) { 
     self.__source = list 
    } 

    func makeIterator() -> abcIterator { 
     return abcIterator(self.__source!); 
    } 
} 

Я, вероятно, отсутствует что-то очень простой здесь. Когда я пытаюсь использовать коллекцию так:

var dict : [String:abc] = [String:abc](); 
    dict["abba"] = abc("John Smith"); 

    for (key,value) in abcCollection(dict) { 
     print(key, value.getName()); 
    } 

Я получаю сообщение об ошибке: Expression типа «abcCollection» неоднозначно без больше контекста

Кто-нибудь есть идеи, как сделать его работу? Чего не хватает? У меня есть ощущение, что этот ответ имеет информацию, мне нужно ...

Swift 2 to 3 Migration for Swift Sequence Protocol

ответ

2

Проблема в исходном коде, что abcCollection(dict) возвращается последовательность abcContainer объектов, а также тех, кто не может быть назначен (key, value) кортежа.

Вы можете достичь своей цели с

class abcCollection : Sequence { 

    private var __source : [String:abc] 

    init(_ list: [String:abc]) { 
     self.__source = list 
    } 

    public func makeIterator() -> AnyIterator<(AnyObject,abcContainer)> { 
     let mapped = self.__source.lazy.map { 
      ($0.key as AnyObject, abcContainer($0.value)) 
     } 
     return AnyIterator(mapped.makeIterator()) 
    } 
} 

Изготовление __source не опциональным делает все (опционально) unwrappings избыточную и lazy.map { ... } возвращает лениво оцененную последовательность пар ключ/значение, которое затем тип- стерта.

+0

Спасибо! Хорошие тонкие точки. –

2

Хорошо, возможно, ответ был abcIterator не было необходимости, вы могли бы определить итератор непосредственно только, как сделано в связанном ответ как это:

class abcCollection : Sequence { 

    private var __source : [String:abc]?; 

    init(_ list: [String:abc]) { 
     self.__source = list 
    } 

    public func makeIterator() -> AnyIterator<(AnyObject,abcContainer)> { 

     var it = self.__source?.makeIterator(); 
     return AnyIterator { 
       let n = it?.next(); 
       if n == nil { return nil } 
       return (n?.key as AnyObject, abcContainer((n?.value)!)) 
     } 

    } 
} 

После этого пользовательская коллекция вернула завернутые объекты правильно.

Смежные вопросы