2013-11-27 1 views
2

다음 코드를 사용하여 하나의 인수 만 제한하려고합니다. 그러나 first :: NIL에서 다음과 같은 오류가 발생 했습니까?간단히 구문 분석 명령 줄 인수

 
Error 1 This expression was expected to have type 
    string []  
but here has type 
    'a list 
[<EntryPoint>] 
let main argv = 

    match argv with 
    | first :: NIL -> 
     .... do something with first 
    | _ -> failwith "Must have only one argument." 
+1

당신이 제 3 자 lib 디렉토리를 원하는 경우에, 나는 F 번호 cmd를 줄 도구에 대한 [UnionArgParser] (https://github.com/eiriktsarpalis/UnionArgParser)를 사용하여 좋아한다. –

답변

4

라인 인수 배열되지 목록으로 전달되는 명령.

정확히 하나 개의 인수를 기대한다면 이런 식으로 뭔가를 수행

허용 대답에 언급 한 바와 같이
match argv with 
| [|first|] -> 
    // .... do something with first 
| _ -> failwith "Must have only one argument." 
+0

배열을 암시 적으로 목록에 캐스트 할 수 있다고 생각했습니다. – ca9163d9

+0

@ dc7a9163d9 F #에서는 개체의 메서드에 매개 변수를 전달할 때를 제외하고는 암시 적 캐스트와 같은 것이 없습니다. 자세한 내용은 다음을 참조하십시오. http://msdn.microsoft.com/en-us/library/vstudio/dd233220.aspx – mydogisbox

+1

배열이 시퀀스를 예상하는 함수에 인수로 전달되면 배열을 암시 적으로 캐스트 캐스트 할 수 있습니다. . 목록에 캐스팅하지 않고 시퀀스 (IEnumerable <>)로 전송할 때 적용됩니다. 이는 배열이 IEnumerable <>을 구현하기 때문입니다. F # "목록"(좋은 구문 지원 모두)은 F #에 고유 한 유형 (단일 연결 목록 구현)인데, IEnumerable과 동일하지는 않습니다 (구현하지만). –

3

은 "인수"를 엔트리 포인트에 인수가 배열이 아닌 목록입니다, 그래서 당신은 그것을 사용할 수 없습니다 리스트 일치의 구문

위에서 제안한 것처럼 배열에서 일치시키는 대신 실제 인수로 인수를 바꿔서 일치시킬 수 있습니다. 나는 커맨드 라인 인자를 다루는 매우 유용한 방법이라는 것을 알게되었다. 예를 들어 :

[<EntryPoint>] 
let main args = 
    let arglist = args |> List.ofSeq 
    match arglist with 
    | first :: [] -> 
    // do something with 'first' 
    | _ -> // catches both the no-argument and multi-argument cases 
    printfn "Usage : " 
    // print usage message 

편집 : 여기에서 이동하는 방법은 두 가지가 있습니다 더 복잡한 예제로. 물론 더 복잡한 경우를 매치에 추가하거나 옵션 목록을 구문 분석하여 재귀 적 방법으로 옵션 및 인수를 나타내는 객체를 작성할 수 있습니다. 후자는 여기에 적합하기에 너무 복잡해 지겠지만보다 복잡한 일치 사례의 예로서, 실행 파일이 대상 파일에서 작동하는 "명령"을 허용하는 최근 작업과 관련된 코드가 있으며 각 명령 이 다른 추가 인수

[<EntryPoint>] 
let main args = 
    let arglist = args |> List.ofSeq 
    match arglist with 
    | target :: "list" :: [] -> 
    listContent target 
    | target :: "remove" :: name :: [] -> 
    removeContent target name 
    | target :: "add" :: name :: [] -> 
    addContent target name 
    | target :: "addall" :: names -> 
    for name in names do 
     addContent target name 
    | _ -> // catches cases not covered above 
    printfn "Usage : " 
    // print usage message 
+0

감사. 좀 더 복잡한 구문 분석의 예를 들어 줄 수 있습니까? 유용 할 수 있습니다. f #에서 제 3 자 인수 라이브러리를 사용해야하는지, 아니면 충분히 강력하기 때문에 필요하지 않은지 궁금합니다. – ca9163d9

0

(각 명령은 구현이 나는 간결함을 위해 남겨 함수를 호출)하는 방법, 개별 명령을 구문 분석 복구의 내용에 실패 없음 및 일부를 표시하지 않는 옵션을 반환하는 활성 패턴에 대한 매개 변수는 자체 전용 유형에 자리 잡고있을 수 있습니다. "argv"를 "string list"로 변환하는 것은 F #의 목록 구문의 편리함 때문에 편의상 사용됩니다. 참고 : 여기에는 일반적으로 불필요한 많은 유형 주석이 있습니다.

type Cmd1Parms = .... 
type Cmd2Parms = .... 

let performCmd1 cmd1Parms = ... 
let performCmd2 cmd2Parms = ... 
let commandNotFound argL = ... 

let (|ParseForCmd1|_|) argL : Cmd1Parms option = .... 
let (|ParseForCmd2|_|) argL : Cmd2Parms option = .... 

[<EntryPoint>] 
let main argv = 
    let argL = List.ofSeq<string> argv 
    match argL with 
    | ParseForCmd1 cmd1Parms -> performCmd1 cmd1Parms 
    | ParseForCmd2 cmd2Parms -> performCmd2 cmd2Parms 
    | _      -> commandNotFound argL