2016-10-07 2 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 오히려 혼란 컴파일러 오류를 보여줍니다 '! UnsafePointer'

예상 인수 유형 유형의 값 'UnsafeMutablePointer < _>을'변환 할 수 없습니다 혼란

, 내가 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으로 유추하여 함수 정의와 일치시킵니다.

스위프트가 이 아니기 때문에 으로 컴파일되지 않습니다. 형식간에을 변환하십시오.

또는 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 매개 변수를 사용하는 대신 의 지역 변수 복사본을 만드는 것이 좋습니다 것입니다. 단순한 오류는 최악입니다. –