문제

좋은 내용 잘 읽었습니다 전문가 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() 왜냐하면:

  1. PropertyName 모든 유형의 속성이 될 수 있습니다.문자열이 아닌 경우에도 구조화된 형식이 적용됩니다. 돈 사임의 블로그 이런 방식으로 트리를 재귀적으로 형식화하는 예를 제공합니다.

  2. 계산된 속성일 수도 있습니다.그래서 당신은 실제로 얻을 수 있습니다 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 방법을 무시하면 그렇게해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top