3

私が抱えている問題を示すために、いくつかのテストコードを作成しました。

これはプレイグラウンドで問題なくコンパイルされますが、プロジェクトに入れようとすると、Xcode は次の警告を表示します: Treating a forced downcast to 'String' as optional will never produce 'nil'30行目。問題を解決するための 2 つの提案が与えられました。

  1. Use 'as?' to perform a conditional downcast to 'String'、これはまったく意味がありません。ただし、警告/エラーなしでコンパイルされます。これは、オプションの値をオプションではないタイプの に割り当てているため、奇妙に思えますString

    ダウンキャストが成功するかどうかわからない場合は、型キャスト演算子の条件付き形式 (as?) を使用します。この形式の演算子は常にオプションの値を返し、ダウンキャストが不可能な場合、値は nil になります。これにより、ダウンキャストが成功したかどうかを確認できます。

    Swift 言語ガイドから。

    変換が失敗した場合に割り当てたいと思われる場合をnil除き (したがって、辞書のエントリを削除します)、これは意味がありません。特に、文字通りそれがString.

  2. Add parentheses around the cast to silence this warning、これは無意味に思えますが、警告を黙らせますこれは奇妙なことのように思えますが、繰り返しますが、自分がやろうとしていることを本当にやりたいと思っていることを確認する方法としては不十分かもしれません.


どちらの選択肢が正しいか、どちらでもないか? この警告の原因は何ですか?

4

2 に答える 2

6

正しい解決策は、強制アンラップ オペレーターの代わりにオプションのバインディングを使用することです!value != nil実際には、チェックをswitchステートメントに組み込むことができます 。

for (key, value) in dict {
    switch value {
    case let s as String:
        newDict[key] = s
    case let i as Int:
        newDict[key] = String(i)
    case let b as Bool:
        newDict[key] = b ? "1" : "0"
    case let v?:   // value is not `nil`
        newDict[key] = String(v)
    default:       // value is `nil`
        break
    }
}
于 2016-06-05T15:55:11.770 に答える
0

関数の結果をキャストして、AnyObject?明示的にアンラップされたオプショナルを一致させ、回避する方法を示すように変更されたコードを次に示します。

func returnsAString() -> AnyObject? {
  return "I am a String." as? AnyObject
}

func returnsAnInt() -> AnyObject? {
  return Int(123) as? AnyObject
}

func returnsABool() -> AnyObject? {
  return true as? AnyObject
}

func returnsNilBool() -> AnyObject? {
  return nil as Bool? as? AnyObject
}

var dict    : [String : AnyObject?] = [String : AnyObject?]()
var newDict : [String : String    ] = [String : String    ]()

dict["string"] = returnsAString()
dict["int"] = returnsAnInt()
dict["bool"] = returnsABool()
dict["nil"] = returnsNilBool()

for (key, value) in dict {
    switch value {
    case let value as String:
      newDict[key] = value
    case let value as Int:
      newDict[key] = String(value)
    case let value as Bool:
      newDict[key] = (value ? "1" : "0")
    default:
      newDict[key] = "nil"
    }
}

print("Dict: \(dict)")
print("newDict: \(newDict)")

// Dict: ["nil": nil, "int": Optional(123), "bool": Optional(1), "string": Optional(I am a String.)]
// newDict: ["nil": "nil", "int": "123", "bool": "1", "string": "I am a String."]
于 2016-06-05T15:59:02.917 に答える