2011-12-21 3 views
13

튜플의 항목에는 이름이 없으므로 각 항목의 의미를 문서화하는 명확한 방법이없는 경우가 많습니다. 나는 분명히 제 1 및 제 2 항목은 각각 보낸 사람과받는 사람의 이름입니다 있는지 확인하려면매개 변수 의미를 나타 내기 위해 형식 별칭을 사용하는 것이 일반적인 방법입니까?

type NetworkEvent = 
| Message of string * string * string 
| ... 

이의 예를 들어

는 노조를 차별. 이 같은 것을 할 수있는 좋은 방법은 다음과 같습니다

type SenderName = string 
type RecipientName = string 

type NetworkEvent = 
| Message of SenderName * RecipientName * string 
| ... 

C/C++ 라이브러리의 많은 매개 변수 이름은 많은 경우에 선택에도 불구하고 유형 (예 : win32.h)의 확산, 그러나 그 언어를 , 그것은 여전히 ​​행해질 수 있습니다. F #에서는 그렇지 않습니다.

+3

F # 3.1에서는 이러한 필드가 이름을 가질 수 있습니다. –

+0

@JamesMoore 네, 저를 행복하게합니다 : D –

답변

10

type NetworkEvent2 = 
    | UDPMessage of string * string * string 
    | Broadcast of string * string * string 
    | Loopback of string * string * string 
    | ConnectionRequest of string 
    | FlushEventQueue 

.많은 데모에서 동일한 접근법을 사용합니다 (for example this one 참조). 일부 사용자는 프로덕션 응용 프로그램에서도이 방법을 사용합니다.

형식 별칭 사용 :이 방법을 사용하면 IntelliSense에서 볼 수있는 문서를 추가 할 수 있지만 형식 시스템을 통해 전파되지는 않습니다. 별칭 형식의 값을 사용하면 컴파일러에서 string으로 처리하므로 어디서나 추가 설명서가 표시되지 않습니다.

단일 케이스 유니온 사용이 패턴은 F # 컴파일러의 일부 위치에서 사용되었습니다. 유형 SenderNamestring와 다른 유형 실제로 때문에 (다른 한편으로는,이 작은 약간의 성능 저하가있을 수 있습니다), 타입 별칭을 사용하는 것보다 더 눈에 보이는 정보를한다 :

type SenderName = SenderName of string 
type RecipientName = RecipientName of string 
type NetworkElement = 
    | Message of SenderName * RecipietName * string 

match netelem with 
| Message(SenderName sender, RecipientName recipiet, msg) -> ... 

사용 기록 : 이 방법은 명시 적으로 노조 케이스 정보를 전달할 레코드를 정의합니다. 이것은 구문 론적으로 장황 하긴하지만, 아마도 가장 접근하기 쉬운 방식으로 추가 정보를 추가 할 것입니다. 레코드에서 패턴 일치를 계속 사용하거나 도트 표기법을 사용하여 요소에 액세스 할 수 있습니다. 또한 개발하는 동안 새 필드를 추가하는 것이 더 쉽습니다.

type MessageData = 
    { SenderName : string; RecipientName : string; Message : string } 
type NetworkEvent = 
    | Message of MessageData 

match netelem with 
| Message{ SenderName = sender; RecipientName = recipiet; Message = msg} -> ... 
+3

up-votes를 기반으로하면 소수의보기 일 수 있지만 기록 또는 단일 케이스 노조의 자세한 표시는 내 마음. 그것은 전체적으로 노동 조합의 간결함/통사론 적 편리 성을 무효화합니다. 이것은 Intellisense에서 가장 잘 해결 한 문제인 것처럼 보입니다. 필드에 주석을 달 수있는 방법이 제공되면 유형 및 코딩 스타일을 변경하지 않아도됩니다. – Daniel

+1

이 (그렇지 않으면 우수) 대답은 업데이트가 필요할 수도 있습니다. 이제'type X = Msg of Sender : string * Recip : string'을 할 수 있습니다. 그리고이 필드들도 사용할 수 있습니다 :'let x = X (Sender = "Foo", Recip = "Bar")'. 레코드와 같지만 구문이 다릅니다. – Abel

1

제 생각 엔이 경우에는 순서가 중요하다는 사실을 강조하기 위해 튜플의 처음 두 요소에 레코드 유형을 사용하는 것이 좋습니다.

번호는

, 당신은 약간 더 우아한 뭔가 측정 단위를 사용하여 작업을 수행 할 수 있지만, 내가이 문제 아무것도 표시되지 않습니다

+0

레코드의 확산은 그다지 좋지 않을까요 - 악화되지 않는다면, 많은 'NetworkEvents'가 있을까요? 유사한 매개 변수 이름을 가진 많은 수의 레코드가있을 때 유형 유추가 실제로 혼란스러워지면 모든 단일 필드를 완전히 정규화해야합니다. –

+0

@ReiMiyasaka - 사실 상황이 그렇게 나쁘지는 않습니다. 레코드를 인스턴스화 할 때 언급 한 첫 번째 필드를 완전히 정규화하면 다른 레코드가 올바르게 해석됩니다. – Kit

1

문자열이 작동하지 않습니다,하지만에 대한 성가신 가진 10 별칭을 얻을 수 있습니다 예를 들어 입니다. 그게 너를 괴롭히지 않는다면 나는 말한다. 개인적으로 다음과 같은 것을 지원해 주시기 바랍니다 :

type NetworkEvent = 
| Message of SenderName:string * RecipientName:string * string 
| ... 

그런 다음 Intellisense가 도움을 줄 수 있습니다. (편집 :이 제안에 투표 here)

사례에 필드가 두 개 이상이거나 같은 유형이 여러 개있는 경우 클래스 계층 구조를 대신 사용할 수 있습니다.

+0

그래, C#만큼 IntelliSense를 풍부하게 사용하는 것이 불가능 해지는 F # 구문의 측면이 많습니다. –

+0

최근 개선 된 기능이 있습니다. "F # 3.1부터는 개별 필드에 이름을 지정할 수 있지만 이름은 선택 사항입니다. 대소 문자가 다른 필드의 이름이 지정되어 있어도 마찬가지입니다." http://msdn.microsoft.com/en-us/library/dd233226.aspx –

6

나는 인터넷과 책에서 F #의 나의 요금 점유율을 읽었지만 아무도 문서의 형식으로 별칭을 사용하는 것을 본 적이 없다. 그래서 나는 그것이 표준적인 관행이 아니라고 말할 것입니다. 또한 코드 중복 형태로 볼 수도 있습니다.

일반적으로 특정 튜플 표현은 함수 내에서 임시 데이터 구조로만 사용해야합니다. 오랫동안 튜플을 저장하거나 다른 클래스간에 전달하는 경우에는 레코드를 만들어야합니다.

여러 클래스에 걸쳐 차별화 된 공용체를 사용하려는 경우 제안한대로 레코드를 사용하거나 아래의 방법으로 모든 메서드를 차별화 된 공용 영역으로 유지하십시오. 튜플 정말 편의상하고 코드가 성장함에 따라 기록을 교체해야하므로

type NetworkEvent = 
    | Message of string * string * string 

    static member Create(sender, recipient, message) = 
     Message(sender, recipient, message) 

    member this.Send() = 
     math this with 
     | Message(sender, recipient, message) -> 
      printf "Sent: %A" message 

let message = NetworkEvent.Create("me", "you", "hi") 

당신은 records in pattern matching를 사용할 수 있습니다.

식별 된 노동 조합에 동일한 서명이있는 튜플이있는 경우 두 개의 구분 된 노동 조합으로 구분해야합니다. 이렇게하면 같은 서명을 가진 여러 레코드를 가질 수 없습니다. 나는이 문서의 목적을 위해 유형 별칭을 사용하여 사용자의 차별 노동 조합을 문서화 할 수있는 좋은 간단한 방법이라고 생각

type MessageType = 
    | UDPMessage 
    | Broadcast 
    | Loopback 

type NetworkEvent = 
    | Message of MessageType * string * string * string 
    | ConnectionRequest of string 
    | FlushEventQueue 
관련 문제