F #에서 '인라인'사용
inline
F # 의 키워드는 내가 예를 들어 C에서 사용했던 것과는 다소 다른 목적을 가지고있는 것 같습니다. 예를 들어, 함수의 유형에 영향을 미치는 것 같습니다 ( "정적으로 확인 된 유형 매개 변수"란 무엇입니까? 모든 F # 유형이 아님). 정적으로 해결 되었습니까?)
inline
함수 는 언제 사용해야 합니까?
inline
키워드는 함수 정의를 사용하는 인라인 코드에 삽입되는 것을 나타냅니다. 대부분의 경우 이는 함수 유형에 영향을주지 않습니다. 그러나 드물게 .NET에서 컴파일 된 코드 형식으로 표현할 수 없지만 함수가 인라인 될 때 적용 할 수있는 제약 조건이 있기 때문에 좀 더 일반적인 유형의 함수로 이어질 수 있습니다.
이것이 적용되는 주요 사례는 연산자를 사용하는 것입니다.
let add a b = a + b
단형 추론 된 유형을 갖게됩니다 (아마도 int -> int -> int
,하지만 float -> float -> float
해당 유형에서이 함수를 대신 사용하는 코드가있는 경우 와 같을 수 있습니다 ). 그러나이 함수를 인라인으로 표시하면 F # 컴파일러가 다형성 유형을 유추합니다.
let inline add a b = a + b
// add has type ^a -> ^b -> ^c when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
.NET의 컴파일 된 코드에서이 유형 제약 조건을 첫 번째 클래스 방식으로 인코딩하는 방법은 없습니다. 그러나 F # 컴파일러는 함수를 인라인하는 사이트에서이 제약 조건을 적용하여 모든 연산자 사용이 컴파일 타임에 해결되도록 할 수 있습니다.
유형 매개 변수 ^a
, ^b
그리고는 ^c
, "정적 유형 매개 변수를 해결"하는 인수의 유형이 정적으로 이러한 매개 변수를 사용하는 사이트에 알려진해야한다는 것을 의미합니다. 이는 일반 유형 매개 변수 (예 : 'a
, 'b
등) 와 대조적입니다 . 여기서 매개 변수는 "나중에 제공되지만 어떤 것이 든 될 수있는 유형"과 같은 것을 의미합니다.
inline
함수 는 언제 사용해야 합니까?
inline
실제로 키워드 의 가장 가치있는 응용 프로그램은 완전히 최적화 된 단일 코드 조각을 생성하기 위해 함수 인수도 인라인되는 호출 사이트에 고차 함수를 인라인하는 것입니다.
예를 들어, inline
다음 fold
함수는 5 배 더 빠릅니다.
let inline fold f a (xs: _ []) =
let mutable a = a
for i=0 to xs.Length-1 do
a <- f a xs.[i]
a
이것은 inline
대부분의 다른 언어에서 수행 하는 것과 거의 유사 하지 않습니다. C ++에서 템플릿 메타 프로그래밍을 사용하여 유사한 효과를 얻을 수 있지만 F #은 inline
.NET 메타 데이터를 통해 전달 되기 때문에 컴파일 된 어셈블리간에 인라인 될 수도 있습니다 .
첫 번째 사용 사이트에서만 유형을 평가 (추론)하는 일반 함수와 달리 각 사용 사이트에서 유형을 (재) 평가해야하는 함수를 정의해야하는 경우 인라인을 사용해야합니다. , 그런 다음 그 이후의 다른 모든 곳에서 첫 번째 유추 된 형식 서명을 사용하여 정적으로 형식화 된 것으로 간주됩니다.
인라인의 경우 함수 정의는 효과적으로 일반 / 다형성 인 반면 일반 (인라인이 아닌) 경우 함수는 정적으로 (그리고 종종 암시 적으로) 형식화됩니다.
따라서 인라인을 사용하는 경우 다음 코드 :
let inline add a b = a + b
[<EntryPoint>]
let main args =
let one = 1
let two = 2
let three = add one two
// here add has been compiled to take 2 ints and return an int
let dog = "dog"
let cat = "cat"
let dogcat = add dog cat
// here add has been compiled to take 2 strings and return a string
printfn "%i" three
printfn "%s" dogcat
0
빌드하고 컴파일하여 다음 출력을 생성합니다.
3
dogcat
즉, 정수에 더하는 함수와 두 문자열을 연결하는 함수를 모두 생성하는 데 동일한 추가 함수 정의가 사용되었습니다 (실제로 +에 대한 기본 연산자 오버로딩도 인라인을 사용하여 내부에서 수행됨).
이 코드는 add 함수가 더 이상 인라인으로 선언되지 않는다는 점을 제외하면 동일합니다.
let add a b = a + b
[<EntryPoint>]
let main args =
let one = 1
let two = 2
let three = add one two
// here add has been compiled to take 2 ints and return an int
let dog = "dog"
let cat = "cat"
let dogcat = add dog cat
// since add was not declared inline, it cannot be recompiled
// and so we now have a type mismatch here
printfn "%i" three
printfn "%s" dogcat
0
컴파일되지 않고 다음 불만 사항에 실패합니다.
let dogcat = add dog cat
^^^ - This expression was expected to have type int
but instead has type string
인라인을 사용하는 것이 적절한 경우에 대한 좋은 예는 두 개의 인수가있는 함수의 인수 적용 순서를 반대로하는 일반 함수를 정의하려는 경우입니다.
let inline flip f x y = f y x
이 질문에 대한 @pad의 답변에서와 같이 Array, List 또는 Seq의 N 번째 요소를 얻기위한 인수 순서가 다릅니다 .
The F# component design guidelines only mention a little about this. My recommendation (that aligns well with what's said there) is:
- Don't use
inline
- Exception: you might consider using
inline
when writing mathematical libraries to be consumed by other F# code and you want to write functions that are generic over different numeric data types.
- Exception: you might consider using
There are lots of other "interesting" uses of inline and static member constraints for "duck-typing" kinds of scenarios that work a bit like C++ templates. My advice is to avoid all of that like the plague.
@kvb's answer goes into more depth about what 'static type constraints' are.
참고URL : https://stackoverflow.com/questions/3754862/use-of-inline-in-f
'Nice programing' 카테고리의 다른 글
쉼표로 구분 된 목록에 대한 정규식 (0) | 2020.11.23 |
---|---|
Objective-C에서 respondsToSelector를 사용하는 경우 (0) | 2020.11.23 |
CSS에서 : hover 효과를 어떻게 지연시킬 수 있습니까? (0) | 2020.11.23 |
글꼴 색상을 변경하는 방법은 무엇입니까? (0) | 2020.11.23 |
암시 적으로 형식화 된 지역 변수 사용 (0) | 2020.11.23 |