2016-06-28 2 views
0

F #에서 JSON을 구문 분석 (예 : FSharp.Data 덕분에 유형 공급자가있는 경우)하는 것이 더 예리하지만 'fsx 파일에서이 작업을 수행하고 있으며 Nuget + Paket 도구를 다루지 않으려 고합니다.), 여기 System.Web.Script.Serialization.JavaScriptSerializer을 사용하고 있습니다.F # : System.Collections.Dictionary에서 요소를 찾을 때 이상한 컴파일러 오류가 발생합니다.

나는이 funcion로, 사전의 요소를 찾을 때 문제는 다음과 같습니다

let isTestNet(): bool = 
    let json = SomeFuncThatGivesMeAString() 
    let jss = new JavaScriptSerializer() 
    let dict = jss.DeserializeObject(json) :?> Dictionary<string, obj> 
    for entry in dict do 
     if (entry.Key.Equals("testnet")) then 
      let result = entry.Value :?> bool 
      result 
    failwith "JSON response didn't include a 'testnet' element? " + json 

컴파일러는 마지막 줄에 두 번째 강조,이 오류와 함께 :

error FS0001: This expression was expected to have type 
    unit  
but here has type 
    bool 

은 무엇입니까 거래? 함수 헤더에 형식을 지정하기도합니다. 왜 유닛을 기대합니까?

+0

함수의 결과 것은 failwith', 이전의 모든 값을 폐기하고 '이다. 그래서 컴파일러는 우리를 위해 당신을 가리 킵니다. –

+1

@FyodorSoikin : 아니요, 'failwith' 대신에 "false"라고해도 같은 오류로 실패합니다. @ildjarn이 맞다 – knocte

+0

'failwith' 대신'false'를 쓰면, 함수의 결과는 항상'false'가되어 항상 이전의 모든 값을 버립니다. 내 의견은 여전히 ​​적용됩니다. –

답변

3

for 표현식은 unit으로 평가 될 것으로 예상됩니다. for의 끝이 이 아닌-unit이라는 표현식을 사용하면 둘러싸는 함수의 반환 값을 어떻게 든 만들지 않습니다. 궁극적으로 for을 뽑아야합니다.

하나의 옵션은 대신 Seq.tryFind을 사용하는 것입니다

let isTestNet() : bool = 
    let dict = 
     let json = (* ... *) 
     let jss = JavaScriptSerializer() 
     jss.DeserializeObject json :?> Dictionary<string, obj> 
    match dict |> Seq.tryFind (fun entry -> entry.Key.Equals "testnet") with 
     | Some entry -> entry.Value :?> bool 
     | _ -> failwith ("JSON response didn't include a 'testnet' element? " + json) 

(Nb를 인해 연산자 우선 순위 오류 메시지에 대한 문자열 연결 괄호로 묶어야합니다합니다.)

이 잘 읽는 동안, Seq.tryFindO (N) 검색을 수행하는 반면 Dictionary은 직접 사용할 경우 O (1) 검색을 수행하므로 사전이 상당한 크기 인 경우이 방법을 사용할 수 없습니다.

이 훨씬 더 효율적으로, 약간 덜 분명 (AntonSchwaighofer의 제안 개선 @ 제외) :

let isTestNet() : bool = 
    let dict = 
     let json = (* ... *) 
     let jss = JavaScriptSerializer() 
     jss.DeserializeObject json :?> Dictionary<string, obj> 
    match dict.TryGetValue "testnet" with 
     | true, (:? bool as value) -> value 
     | true, _ -> failwithf "'testnet' element was not a bool? %s" json 
     | _ -> failwithf "JSON response didn't include a 'testnet' element? %s" json 
+4

Re : 오류 메시지 : 또는 종종 간과 한'failwithf ','failwithf 'JSON 응답과 같이 ... % s "json' –

관련 문제