2016-12-23 2 views
1

Я пытаюсь реализовать структуру с общим типом, который соответствует протоколу Hashable. Может кто-нибудь помочь мне понять, почему я получаю ошибку «Ошибка сегментации: 11» со следующим кодом.Generic Swift struct: Ошибка сегментации: 11

Я бы очень признателен за любые соображения относительно этого.

struct Pmf<Element: Hashable> { 
    typealias Distribution = [Element : Float] 
    fileprivate var normalized = false 

    fileprivate var distribution:[Element : Float] = [ : ] { 
     didSet { 
      self.normalized = false 
     } 
    } 
} 

extension Pmf { 
    init(values: [Element], withProbs probs: [Float]) { 
     for pair in zip(values, probs) { 
      self.distribution[pair.0] = pair.1 
     } 
    } 

    var probDist: Distribution { 
     mutating get { 
      if !normalized { 
       self.normalize() 
      } 
      return self.distribution 
     } 
    } 

    subscript(value: Element) -> Float? { 
     mutating get { 
      if !normalized { 
       self.normalize() 
      } 
      return self.distribution[value] 
     } 
     set(prob) { 
      self.distribution[value] = prob 
     } 
    } 
    mutating func normalize() { 
     for (key, val) in self.distribution { 
      self.distribution[key] = val/Float(self.distribution.count) 
     } 
    } 
} 

var pp = Pmf<String>() 

pp["One"] = 4 
pp["Two"] = 5 
pp["three"] = 5 

print(pp) 
+0

Ваш пример не компилируется, потому что вы не имеют метода 'normalize()'. Кроме того, можете ли вы опубликовать код, который использует эту структуру? – ColGraff

+0

@ColGraff благодарит за ответ. Тем не менее, у меня есть нормализованная функция, я не добавлял ее изначально, чтобы сохранить опубликованный код меньше. Я обновил вопрос с нормализацией функции. Кроме того, образец теста, где Im использует эту структуру. Тем не менее, ошибка является ошибкой сегментации: 11 –

+0

Да. Я пытаюсь преобразовать часть моего кода, написанного для байесовского вывода в Python ранее, в Swift для практики. –

ответ

1

Кажется, вам нужно немного трюк, чтобы определить инициализатор для типа значения в расширении:

Добавьте одну строку в init(values:withProbs:), как показано ниже:

init(values: [Element], withProbs probs: [Float]) { 
    self.init() //<- 
    for pair in zip(values, probs) { 
     self.distribution[pair.0] = pair.1 
    } 
} 

Во всяком случае компиляторы не должны вылетать с SegFault 11. Даже если исходный код имеет некоторые ошибки в нем.

Лучше послать Bug Report to Apple или до swift.org.

1

Я начинаю писать отчет об ошибке для аналогичной ситуации (добавление метода замедления с использованием общего типа с ассоциированным типом) и получал ошибки сегментации в каждой возможной комбинации, которую я пробовал.

Я начал писать «Минимальный проверяемый пример» на игровой площадке и обнаружил, что не могу воспроизвести ошибку.

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

Я объединил два исходных файла и не обнаружил ошибок сегментации !!

Это заняло несколько часов моего времени, чтобы отследить, надеюсь, что это поможет кому-то еще.

Update: Представлено ошибка для этой ошибки, если вы встречая это тоже, пожалуйста, добавить комментарий, чтобы позволить команде знаю, что вы уже сталкивались с этим: https://bugs.swift.org/browse/SR-3595

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