2016-01-20 62 views
5

我有一些JSON,帶有要輸入Elm的「type」屬性。例如{ "id": "abc", "type": "thing" }但是,如果我使用type作爲屬性定義類型別名,則編譯器會抱怨。例如,Elm:爲「JSON」輸入別名,並輸入「type」屬性

type alias Foo = { 
     id: String 
    , type: String 
} 

產生

It looks like the keyword `type` is being used as a variable. 

3│  , type: String 
      ^
Rename it to something else. 

真的?我必須重命名屬性?有沒有辦法引用或轉義它,所以它會編譯?

回答

6

是,type是保留關鍵字,不能用作記錄中的字段名稱。

在榆樹和Haskell,你的情況做最普通的事情似乎是追加單引號,因此它成爲type',和你的類型定義變得

type alias Foo = 
    { id: String 
    , type': String 
    } 

這有它的起源在來自數學的prime symbol。它看起來可能很奇怪,但它是有效的語法。

然後,您可以使用下面的Json解碼器到JSON轉化爲富:

fooDecoder = 
    Json.object2 
    Foo 
    ("id" := Json.string) 
    ("type" := Json.string) 

注意,在榆樹的確切字段名並不需要匹配的JSON字段名。

很少會找到一種語言,可以讓您使用關鍵字作爲未經轉義的變量名稱。這種行爲並不是Elm獨有的。

+0

追加單引號不會逃避字段名稱,但它會將其更改爲不同的名稱。 – noah

+0

我已經更新了我的答案,以顯示JSON中的字段名稱如何不需要匹配它解碼到的Elm字段。 –

+0

在名字中使用單引號在Elm 0.16中至少有錯誤。它成爲生成的JS中字符串文字的開始。使用_而不是很好。 –

-1

有沒有逃脫。榆樹是不妥協的。

+0

一種嚴酷的行爲。如果某人正在使用他無法控制的API,該怎麼辦? – marcosh

+0

@marcosh您可以將關鍵字翻譯爲另一個字段/可擴展名稱,並且該名稱僅在Elm中使用。如果您通過端口輸出到JS,則必須將其編碼回去。所以字段名稱不會完全匹配JSON屬性名稱,但它不是使用任何類型的JSON工作的障礙。只是惱人的IMO – noah

2

在oscpad中,我通過websockets在我的json接口中使用「type」字段。但是我在榆樹唱片中沒有一個名爲type的字段。當我解析JSON時,我只是尋找「類型」字段。我的代碼如下所示:

jsSpec : JD.Decoder Spec 
jsSpec = 
    ("type" := JD.string) `JD.andThen` jsCs 

jsCs : String -> JD.Decoder Spec 
jsCs t = 
    case t of 
    "button" -> SvgButton.jsSpec `JD.andThen` (\a -> JD.succeed (CsButton a)) 
    "slider" -> SvgSlider.jsSpec `JD.andThen` (\a -> JD.succeed (CsSlider a)) 
    "label" -> SvgLabel.jsSpec `JD.andThen` (\a -> JD.succeed (CsLabel a)) 
    "sizer" -> jsSzSpec `JD.andThen` (\a -> JD.succeed (CsSizer a)) 
    _ -> JD.fail ("unkown type: " ++ t)