2015-12-15 1 views
0

я установки два протокола ниже в скор 2протокола типа ограничение двух протоколов

  • Генеративного (из-за отсутствие лучшего названия), который содержит массив элементов и обеспечивает Datasource как функциональность, как и подсчет индекс
public protocol Generative { 
    typealias GeneratedType 

    var elements: [GeneratedType] { get } 
} 

public extension Generative { 
    func count() -> Int { 
     return elements.count 
    } 

    subscript(index:Int) -> GeneratedType? { 
     if index >= count() { 
      return nil 
     } 
     return elements[index] 
    } 

} 

public protocol Selectable { 
    typealias SelectableType: Hashable 

    var selectedElements: Set<SelectableType> { get set } 

} 

extension Selectable { 
    public func isSelected(elem: SelectableType) -> Bool { 
     return selectedElements.contains(elem) 
    } 

    public mutating func addSelection(elem: SelectableType) { 
     selectedElements.insert(elem) 
    } 

    public mutating func removeSelection(elem: SelectableType) { 
     selectedElements.remove(elem) 
    } 

    public mutating func clearSelections() { 
     selectedElements.removeAll() 
    } 
} 

таким образом, в случае, если объект реализует как генеративный и Выбирается тогда я хочу, чтобы иметь возможность вернуть выбранные индексы, так что я написал эту функцию:

func selectedIndices<S: Selectable where S: Generative, S.GeneratedType == S.SelectableType>(ds: S) -> [NSIndexPath] { 
    var selections: [NSIndexPath] { 
     return ds.selectedElements 
      .map{ (p: S.GeneratedType) -> NSIndexPath? in 
       if let idx = ds.elements.indexOf(p) { idx 
        return NSIndexPath(forRow: idx, inSection: 0) 
       } 
       return nil 
      } 
      .filter{ $0 != nil } 
      .map{ $0! } 
    } 


    return selections 
} 

по какой-то причине компоновщик печатает:

Сбой команды из-за сигнала: неисправность Сегментация: 11

Не уверен, почему это, я не могу понять, еще один способ указать эту функцию для работы с объектами, которые реализуют оба протокола и связанные с ними типы, соответствующие ... Любые идеи?

P.S. код в Сущностью: https://gist.github.com/edwardIshaq/715b0e134fb47d2e28cc

------- UPDATE удаление вычисляемого свойства, казалось, сделать трюк:

func selectedIndices<S: Selectable where S: Generative, S.GeneratedType == S.SelectableType>(ds: S) -> [NSIndexPath] { 
    return ds.selectedElements 
     .flatMap { (p: S.GeneratedType) -> NSIndexPath? in 
      if let idx = ds.elements.indexOf(p) { idx 
       return NSIndexPath(forRow: idx, inSection: 0) 
      } 
      return nil 
    } 
} 
+0

Это может быть длинный выстрел, но попробуйте очистить проект и строительство снова. Я видел эту ошибку только один раз и помогал cmd + shift + k. – 66o

+0

p.s. вместо '.map {return a optional} .filter {$ 0! = nil} .map {$ 0! } ', вы можете написать' .flatMap {return a optional} ', он будет делать то же самое. –

+0

@ 66o Я пробовал чистить и строить, и все это, Linker продолжает рушиться ... –

ответ

2

компилятор никогда не должен врезаться, но это выглядит как причина проще, кажется, делать с родовыми функциями, которые используют вычисляемые свойства внутренне, это так просто, как я могу получить его:

// swiftc crashes when compiling this 
func f<T>(t: T) -> Int { 
    var v: Int { 
     return 0 
    } 
    return v 
} 

так как обходной путь, попробуйте рефакторинга кода, чтобы не использовать вычисляемое свойство.

Вы можете сделать это, и записать это как продолжение двух протоколов, как это:

extension Selectable 
where Self: Generative, 
     Self.GeneratedType == NSIndexPath, 
     Self.SelectableType == NSIndexPath 
{ 
    func selectedIndices() -> [NSIndexPath] { 
     return self.selectedElements.flatMap { 
      self.elements.indexOf($0).map { NSIndexPath(index: $0) } 
     } 
    } 
} 
+0

Это похоже на трюк, спасибо :) –

+0

Любая идея, если можно включить эту функцию как расширение одного из протоколов? –

+0

Yup, добавлена ​​версия, которая это делает. –