2016-10-07 9 views
4

入れ子にされたクロージャで取り込まれた値を使用するための適切な構文は何ですか?入れ子になったクロージャでの値の取り込み

zlibライブラリを使用して、整数値からCRC32を計算するための次の作業コードがあります。

func testCrc() 
{ 
    var x: UInt32 = 0xffffffff 

    let result = withUnsafePointer(to: &x, { 
     $0.withMemoryRebound(to: Bytef.self, capacity: 4) { 
      crc32(0, $0, 4) 
     } 
    }) 

    XCTAssertEqual(0xffffffff, result) 
} 

任意の値からCRC32を計算できるスタンドアロン汎用関数を作成したいと考えています。これを行うためには、値そのもののほかに、サイズを計算して渡す必要があるので、上記のコードで使用したように、明示的なサイズを使用することはできません - 4 -

しかし、計算されたサイズを内部クロージャに渡す正しい構文を見つけるのに問題があります。上記のコード

func calculateCrc32<T>(_ crc: UInt, value: inout T) -> UInt 
{ 
    let size = MemoryLayout.size(ofValue: value) 
    let result = withUnsafePointer(to: &value, { 
     $0.withMemoryRebound(to: Bytef.self, capacity: size) { 
      crc32(crc, $0, size) // error 
     } 
    }) 
    return result 
} 

パラメータ$0ため、むしろ混乱コンパイラのエラーを示しています。

が期待 引数の型に型 'UnsafeMutablePointer < _>' の値を変換できません 'UnsafePointer!'

私はcrc32(crc, $0, 4)crc32(crc, $0, size)を交換する場合、コンパイラが文句を言っていないと機能は4バイトのサイズと値のために適切に動作するため、紛らわしいです。

上記の問題を解決するにはどうすればよいですか?

答えて

4

エラーメッセージは誤解を招く可能性があります。あなたのコードは 「のみ」の問題があること に必要crc32()の最後の引数で、ほとんど正しいuInt

func calculateCrc32<T>(_ crc: UInt, value: inout T) -> UInt 
{ 
    let size = MemoryLayout.size(ofValue: value) 
    let result = withUnsafePointer(to: &value, { 
     $0.withMemoryRebound(to: Bytef.self, capacity: size) { 
      crc32(crc, $0, uInt(size)) 
     } 
    }) 
    return result 
} 

あなたは4 を最後として渡され、その後、「整数リテラル」crc32(crc, $0, 4)を呼び出す場合コンパイラは、タイプ をuIntとして、関数の定義と一致させます。スウィフトは、暗黙のうちにタイプ間を変換しませ を行いますので、

それはcrc32(crc, $0, size)でコンパイルされません。

また、numericCast()を使用してください。これは、さまざまな符号付きおよび符号なし整数型(およびオーバーフロー時のトラップ)間で変換する汎用関数です。それはそれで、

func calculateCrc32<T>(_ crc: UInt, value: T) -> UInt { 
    var value = value 
    let size = MemoryLayout.size(ofValue: value) 
    let result = withUnsafePointer(to: &value, { 
     $0.withMemoryRebound(to: Bytef.self, capacity: size) { 
      crc32(crc, $0, numericCast(size)) 
     } 
    }) 
    return result 
} 
+0

ありがとう:

は、私はまた、それが簡単に 関数を呼び出すことが可能値inoutパラメータを使用しての代わりに 、ローカル変数のコピーを作成することをお勧め。単純なエラーは最悪です。 –

関連する問題