Swift reduce - 為什麼 value 是可選的? (Swift reduce - why is value optional?)


問題描述

Swift reduce ‑ 為什麼 value 是可選的? (Swift reduce ‑ why is value optional?)

為什麼 totalreturn total + 1 行是可選的?

return first.enumerated().reduce(0) { total, letter in
   let index = first.index(first.startIndex, offsetBy: letter.offset)
   if first[index] != second[index]{
       return total + 1
   }
   return total
}

可選類型'Int'的值?必須使用 '??' 將其解包為“Int”類型的值 Coalesce 當可選值包含 'nil' 時提供默認值 使用 '!' 強制解包 如果可選值包含 'nil' 則中止執行

所以這修復了它:

return first.enumerated().reduce(0) { total, letter in
   let index = first.index(first.startIndex, offsetBy: letter.offset)
   if first[index] != second[index]{
       return total! + 1
   }
   return total
}

如果我分解它,添加 let index 時會發生更改....

OK ‑ 這將返回 first 的總數,並且 total 不是可選的:

return first.reduce(0) { total, letter in
    return total + 1
}

OK ‑ 這個枚舉和 total 不是可選的:

p>
return first.enumerated().reduce(0) { total, letter in
    return total + 1
}


參考解法

方法 1:

In order for you to get this result at all (as far as I can tell), the enclosing function must return an Int?. The implication is that reduce can return an optional. Absent the conditional, the compiler can determine that reduce will never return nil, i.e., total is never nil. So, the compiler infers that the return type of the closure is Int. The compiler appears to be entangling type inferencing for the reduce closure and total. Once you add the conditional, the compiler is incapable of determining whether the reduce will return nil or not. Now when it unnecessarily infers the type for total it gets it wrong.

To me this looks like a case of Swift type inferencing gone astray. Clearly, total is never nil based on the documentation of enumerated.

If you modify the code slightly you get the expected result:

   return first.enumerated().reduce(0) { (total: Int, letter) in
       let index = first.index(first.startIndex, offsetBy: letter.offset)
       if first[index] != second[index]{
          return total + 1
       }
       return total
   }

Swift makes a lot of type inferences and it is really great because I get strong typing while retaining many of the benefits of a dynamic language. In my experience, however, swift's inferences can be mystifying sometimes. It handles arcane situations with ease and stumbles over something I think is obvious.

It looks like a bug to me.

(by TurnipdabeetsJohn Morris)

參考文件

  1. Swift reduce ‑ why is value optional? (CC BY‑SA 2.5/3.0/4.0)

#reduce #enumeration #swift






相關問題

Lapack 的行縮減 (Lapack's row reduction)

泡菜cython類 (pickle cython class)

將列表列表減少為字典,以子列表大小為鍵,出現次數為值 (Reduce list of list to dictionary with sublist size as keys and number of occurances as value)

使用 map/reduce 在列表中添加一對數字的差異 (Adding difference of pair of numbers in list using map/reduce)

Python 2.7:使用 reduce 驗證元素是否在列表中 (Python 2.7: Using reduce to verify that elements are in a list)

使用 map/reduce 計算總數 (Using map/reduce to calculate totals)

Swift reduce - 為什麼 value 是可選的? (Swift reduce - why is value optional?)

獲取具有對像一鍵值的數組的平均值 - Javascript (Get the avarage value of array with objects one key value - Javascript)

如何將數據數組轉換為在顫振/飛鏢中展開或折疊的小部件列表? (How to convert an array of data to a list of widgets with expand or fold in flutter/dart?)

樹的字符串路徑 (JavaScript) (String-path to Tree (JavaScript))

如何重命名對像數組中對象的所有鍵? (How does one rename all of an object's keys within an array of objects?)

使用reduce轉換一個js對象 (transform a js object using reduce)







留言討論