2016-12-23 115 views
1

我想實現一個符合Hashable協議的泛型類型的結構。任何人都可以幫助我理解爲什麼我會在下面的代碼中看到「Segmentation fault:11」錯誤。通用Swift結構:分段錯誤: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感謝您的回覆。但是,我確實有一個標準化函數,我並沒有在最初添加它來減少發佈的代碼。我用normalize函數更新了這個問題。另外,一個示例測試,其中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 Appleswift.org

1

我開始爲類似的情況寫一個錯誤報告(使用與關聯類型相關的泛型添加方法減速),並且我嘗試了每個可能的組合都得到了段錯誤。

我開始在操場上寫一個'Minimum Verifiable Example',發現我無法複製這個錯誤。

應用程序和遊樂場的唯一區別在於,應用程序在不同的源文件中有協議和方法。

我組合了兩個源文件,沒有更多的分段錯誤!

這花了幾個小時的時間來追蹤,希望它可以幫助別人。

更新:提交了錯誤此故障,如果你遇到此也請添加評論,讓團隊知道你已經遇到過:https://bugs.swift.org/browse/SR-3595