캐스팅 및 변환(F#)
이 항목에서는 F#의 형식 변환 지원에 대해 설명합니다.
산술 형식
F#에서는 정수와 부동 소수점 형식 사이의 변환 같은 다양한 기본 형식 사이의 산술 변환을 위한 변환 연산자를 제공합니다.정수 및 문자 변환 연산자에는 checked 형식과 unchecked 형식이 있습니다. 부동 소수점 연산자와 enum 변환 연산자에는 그와 같은 형식이 없습니다.unchecked 형식은 Microsoft.FSharp.Core.Operators에 정의되고, checked 형식은 Microsoft.FSharp.Core.Operators.Checked에 정의됩니다.checked 형식은 오버플로를 검사하고 결과 값이 대상 형식의 제한을 초과하면 런타임 예외를 발생시킵니다.
이와 같은 각 연산자의 이름은 대상 형식의 이름과 같습니다.예를 들어 형식이 명시적으로 주석 처리되어 있는 다음 코드에서 byte는 서로 다른 두 가지 의미를 갖습니다.그중 첫째 항목은 형식이고 둘째 항목은 변환 연산자입니다.
let x : int = 5
let b : byte = byte x
다음 표에는 F#에 정의된 변환 연산자가 나와 있습니다.
Operator |
설명 |
---|---|
byte |
8비트 부호 없는 형식인 바이트로 변환합니다. |
sbyte |
부호 있는 바이트로 변환합니다. |
int16 |
16비트 부호 있는 정수로 변환합니다. |
uint16 |
16비트 부호 없는 정수로 변환합니다. |
int32, int |
32비트 부호 있는 정수로 변환합니다. |
uint32 |
32비트 부호 없는 정수로 변환합니다. |
int64 |
64비트 부호 있는 정수로 변환합니다. |
uint64 |
64비트 부호 없는 정수로 변환합니다. |
nativeint |
네이티브 정수로 변환합니다. |
unativeint |
부호 없는 네이티브 정수로 변환합니다. |
float, double |
64비트 배정밀도 IEEE 부동 소수점 숫자로 변환합니다. |
float32, single |
32비트 단정밀도 IEEE 부동 소수점 숫자로 변환합니다. |
decimal |
System.Decimal로 변환합니다. |
char |
유니코드 문자인 System.Char로 변환합니다. |
enum |
열거 형식으로 변환합니다. |
기본 제공 형식 외에도 적절한 시그니처를 통해 op_Explicit 또는 op_Implicit 메서드를 구현하는 형식과 함께 이러한 연산자를 사용할 수 있습니다.예를 들어 형식을 매개 변수로 취하여 int를 반환하는 정적 메서드 op_Explicit을 제공하는 임의의 형식과 함께 int 변환 연산자를 사용할 수 있습니다.반환 형식으로 메서드를 오버로드할 수 없는 일반 규칙에 대한 특별 예외로 op_Explicit 및 op_Implicit에 대해 이를 수행할 수 있습니다.
열거 형식
enum 연산자는 변환할 enum의 형식을 나타내는 형식 매개 변수 한 개를 취하는 제네릭 연산자입니다.이 연산자를 사용하여 열거 형식으로 변환하는 경우 형식 유추를 통해 변환 대상인 enum의 형식을 결정합니다.다음 예제에서 변수 col1은 명시적으로 주석 처리되지 않았지만 나중에 나오는 같음 테스트를 통해 해당 형식을 유추합니다.따라서 컴파일러에서 사용자가 Color 열거형으로 변환하려 한다는 것을 추론할 수 있습니다.또는 다음 예제의 col2에서와 같이 형식 주석을 제공할 수도 있습니다.
type Color =
| Red = 1
| Green = 2
| Blue = 3
// The target type of the conversion is determined by type inference.
let col1 = enum 1
// The target type is supplied by a type annotation.
let col2 : Color = enum 2
do
if (col1 = Color.Red) then
printfn "Red"
대상열거형형식을 명시적으로 형식매개 변수를 다음코딩하다에서 같이 지정할 수도 있습니다.
let col3 = enum<Color> 3
Note열거형의 내부 형식이 호환 형식으로 변환 하는 경우에열거형하는 작업을 비춥니다.다음코딩하다에서는 변환이컴파일하다일치 하지 않기 때문에 실패 int32 및 uint32.
// Error: types are incompatible
let col4 : Color = enum 2u
자세한 내용은 열거형(F#)를 참조하십시오.
개체 형식 캐스팅
개체 계층 구조에서 형식 사이의 변환은 개체 지향 프로그래밍의 근간을 형성합니다.변환에는 두 가지 기본 형식이 있습니다. 그중 하나는 위로 캐스팅하는 형식(업캐스팅)이고 다른 하나는 아래로 캐스팅하는 형식(다운캐스팅)입니다.계층 구조를 위로 캐스팅한다는 것은 파생된 개체 참조에서 기본 개체 참조로 캐스팅한다는 의미입니다.이와 같은 캐스팅은 파생된 클래스의 상속 계층 구조에 기본 클래스가 있는 경우에 한해 작동이 보장됩니다.계층 구조를 아래로 캐스팅한다는 것은 기본 개체 참조에서 파생된 개체 참조로 캐스팅하는 것을 의미하며, 이는 개체가 실제로 올바른 대상(파생) 형식의 인스턴스이거나 대상 형식에서 파생된 형식의 인스턴스인 경우에만 작동합니다.
F#에서는 이러한 변환 형식을 위한 연산자를 제공합니다.:> 연산자는 계층 구조를 위로 캐스팅하고, :?> 연산자는 계층 구조를 아래로 캐스팅합니다.
업캐스팅
대부분의 개체 지향 언어에서는 업캐스팅이 암시적이지만 F#의 규칙은 약간 다릅니다.개체 형식에 대한 메서드에 인수를 전달하면 업캐스팅이 자동으로 적용됩니다.그러나 모듈에 있는 let 바인딩된 함수의 경우 매개 변수 형식을 유연한 형식으로 선언하지 않으면 업캐스팅이 자동으로 이루어지지 않습니다.자세한 내용은 유연한 형식(F#)을 참조하십시오.
:> 연산자는 정적 캐스팅을 수행합니다. 즉, 캐스팅의 성공 여부가 컴파일 타임에 결정됩니다.:> 연산자를 사용하는 캐스팅이 성공적으로 컴파일되면 이는 유효한 캐스팅이므로 런타임에 아무런 문제가 발생하지 않습니다.
upcast 연산자를 사용하여 그와 같은 변환을 수행할 수도 있습니다.다음 식에서는 계층 구조의 상향 변환을 지정합니다.
upcast expression
업캐스팅 연산자를 사용하는 경우 컴파일러는 컨텍스트를 기반으로 하여 사용자가 변환하려는 대상 형식을 유추합니다.컴파일러가 대상 형식을 결정할 수 없으면 오류가 보고됩니다.
다운캐스팅
:?> 연산자는 동적 캐스팅을 수행합니다. 즉, 캐스팅의 성공 여부가 런타임에 결정됩니다.:?> 연산자를 사용하는 캐스팅은 컴파일 타임에 검사되지 않습니다. 대신 런타임에 지정된 형식으로 캐스팅하려는 시도가 이루어집니다.개체가 대상 형식과 호환되면 캐스팅이 성공합니다.개체가 대상 형식과 호환되지 않으면 런타임에 InvalidCastException이 발생합니다.
downcast 연산자를 사용하여 동적 형식 변환을 수행할 수도 있습니다.다음 식에서는 프로그램 컨텍스트를 통해 유추한 형식으로 계층 구조의 하향 변환을 지정합니다.
downcast expression
업캐스팅 연산자의 경우와 마찬가지로 컴파일러에서 컨텍스트를 통해 특정 대상 형식을 유추할 수 없으면 오류가 보고됩니다.
다음 코드에서는 :> 및 :?> 연산자를 사용하는 방법을 보여 줍니다.이 코드를 보면 :?> 연산자는 변환의 성공을 분명하게 예측할 수 있을 때 사용하는 것이 가장 좋다는 사실을 알 수 있습니다. 변환에 실패하면 InvalidCastException이 throw되기 때문입니다.변환이 성공할지 여부를 알 수 없으면 match 식을 사용하여 형식 테스트를 수행하는 것이 더 좋습니다. 이 경우 예외가 발생할 부담이 없기 때문입니다.
type Base1() =
abstract member F : unit -> unit
default u.F() =
printfn "F Base1"
type Derived1() =
inherit Base1()
override u.F() =
printfn "F Derived1"
let d1 : Derived1 = Derived1()
// Upcast to Base1.
let base1 = d1 :> Base1
// This might throw an exception, unless
// you are sure that base1 is really a Derived1 object, as
// is the case here.
let derived1 = base1 :?> Derived1
// If you cannot be sure that b1 is a Derived1 object,
// use a type test, as follows:
let downcastBase1 (b1 : Base1) =
match b1 with
| :? Derived1 as derived1 -> derived1.F()
| _ -> ()
downcastBase1 base1
제네릭 연산자 downcast 및 upcast는 형식 유추에 기반을 두고 인수 형식과 반환 형식을 결정하므로 위 코드의 경우 다음 부분을
let base1 = d1 :> Base1
다음과 같이 바꿀 수 있습니다.
base1 = upcast d1
위 코드에서 인수 형식과 반환 형식은 각각 Derived1 및 Base1입니다.
형식 테스트에 대한 자세한 내용은 일치 식(F#)를 참조하십시오.