printf를 사용하여 사용자 정의 유형의 출력을 어떻게 사용자 정의합니까?
-
16-09-2019 - |
문제
좋은 내용 잘 읽었습니다 전문가 F# 실제 애플리케이션을 구축하는 중입니다.디버깅하는 동안 저는 repl 창에서 내용을 읽을 수 있도록 다음과 같은 fsi 명령을 전달하는 데 익숙해졌습니다.
fsi.AddPrinter(fun (x : myType) -> myType.ToString())
printf 포맷터와 함께 작동하도록 이것을 확장하고 싶습니다. 예를 들어 다음과 같이 입력할 수 있습니다.
printf "%A" instanceOfMyType
사용자 정의 유형에 대한 출력을 제어합니다.이 책은이 작업이 수행 될 수 있음을 암시하지만 (P 93, "일반 구조 형식은 F# 웹 사이트에서 다루는 모든 사용자 정의 데이터 유형, 주제로 작동하도록 확장 될 수 있지만, 방법에 대한 참조를 찾지 못했습니다. 실제로 이것을 달성합니다.방법을 아는 사람 있나요?심지어 가능합니까?
편집하다:
코드 샘플을 포함했어야 했는데, 이는 제가 다루고 있는 레코드 유형입니다.
type myType =
{a: int}
override m.ToString() = "hello"
let t = {a=5}
printfn "%A" t
printfn "%A" (box t)
두 print 문 모두 다음을 생성합니다.
{a = 5;}
해결책
F# 2.0에서 이 작업을 수행하는 올바른 방법은 다음을 사용하는 것 같습니다. StructuredFormatDisplay
예를 들면 다음과 같습니다.
[<StructuredFormatDisplay("hello {a}")>]
type myType = {a: int}
이 예에서는 기본값 대신 {a = 42;}
, 당신은 얻을 것이다 hello 42
.
이는 개체, 레코드 및 공용체 유형에 대해 동일한 방식으로 작동합니다.패턴은 다음 형식이어야 하지만 "PreText {PropertyName} PostText"
(이름 그리고 게시물 텍스트 선택 사항임) 이는 실제로 다음보다 더 강력합니다. ToString()
왜냐하면:
PropertyName
모든 유형의 속성이 될 수 있습니다.문자열이 아닌 경우에도 구조화된 형식이 적용됩니다. 돈 사임의 블로그 이런 방식으로 트리를 재귀적으로 형식화하는 예를 제공합니다.계산된 속성일 수도 있습니다.그래서 당신은 실제로 얻을 수 있습니다
ToString()
다소 우회적인 방식이지만 레코드 및 공용체 유형에 대해 작업하려면 다음을 수행하십시오.[<StructuredFormatDisplay("{AsString}")>] type myType = {a: int} override m.ToString() = "hello" member m.AsString = m.ToString() // a property that calls a method
그런데, ToString()
호출하면 항상 사용됩니다(레코드 및 공용체 유형의 경우에도). printfn "%O"
대신에 printfn "%A"
.
다른 팁
흠 ... 나는 이것에 대한 약간의 변화를 모호하게 기억하지만, 그들이 CTP 전후에 일어난 지 잊어 버린다 (1.9.6.2).
어쨌든 CTP에서는
type MyType() =
override this.ToString() = "hi"
let x = new MyType()
let xs = Array.create 25 x
printfn "%A" x
printfn "%A" xs
VFSI 창에서 평가할 때 내가 원하는 것을 수행합니다.
x;;
xs;;
또한 잘 인쇄합니다. 그래서, 나는 이것이 원하는 것과 어떻게 다른지 불분명하다고 생각합니까?
Tostring 방법을 무시하면 그렇게해야합니다.