[Swift] 제네크스 함수의 유형이 오폭에 빠져

5172 단어 Swift
  • Xcode 6.1.1
  • Playground
  • 알맞은 곳


    RGB 값 등을 처리하는 코드를 썼지만 다음 처리를 수행하는 중 오류가 발생했습니다.
    재현을 목적으로 하는 무의미한 코드
    // 適当
    let a: UInt8 = 230 
    
    // 計算&UInt8の上限を超えないように抑える的な処理
    let b: UInt8 = min(255, Int(a) + 50)
    
    min 함수의 첫 번째 파라미터는 상량형이기 때문에 모드가 모호하지만 두 번째 파라미터는 Int형+상량형이기 때문에 제네릭스 함수min<T>는 T의 유형이 Int라고 생각하고 코드를 썼다.
    그러나 실제min 함수는 매개 변수를 UInt8형으로 수신했고 두 번째 매개 변수는 230 + 50 = 280에서 255를 초과했기 때문에 판정 넘침으로 인해 실행 중 오류가 발생했다.
  • 실제로min함수의 결과를 어떤 함수의 매개 변수에 건네주는 곳에서 발생했다.
  • 확인

    _stdlib_getTypeName 이 함수를 사용하면 유형의 정보를 얻을 수 있을 것 같아서 어떤 유형으로 처리되었는지 이걸로 봅시다.
    먼저 다음과 같이 상수b의 유형이 지정되지 않았습니다.
    let a = UInt8(100)
    
    func gen<T>(value: T) -> T {
        println(_stdlib_getTypeName(value)) // "_TtSi"
        return value
    }
    
    let b = gen(Int(a) + 50)
    
    이때"_TtSi"형이 나타나 기대했던 대로Int형이 움직이고 있다.
    하지만 만지작b 타입은...
    let a = UInt8(100)
    
    func gen<T>(value: T) -> T {
        println(_stdlib_getTypeName(value)) // "_TtVSs5UInt8"
        return value
    }
    
    let b: UInt8 = gen(Int(a) + 50)
    
    이번에 우리는 "_TtVSs5UInt8"UInt8형으로 처리되었다는 것을 알게 되었다.
    Generics의 형은 왼쪽(대입지)의 유형에 영향을 받는다고 한다.
    그럼에도 불구하고 적어도 Int(a)형은 Int형이고, 그 다음에 어떻게 UInt8형으로 변했는지 뜻이 불분명하다.
    무단으로 바꿔도 이상해.

    회피책


    이번 일로 Generix 함수의 반환값을 변환하면 기대했던 것과 같다.
    // 適当
    let a: UInt8 = 230
    
    // 計算&UInt8の上限を超えないように抑える的な処理
    let b: UInt8 = UInt8(min(255, Int(a) + 50)) // 255
    
    런타임 및 오버플로우에서만 발생할 수 있으며 잠재적인 오류가 발생할 수 있습니다.
    조심하세요.

    좋은 웹페이지 즐겨찾기