2011-03-08 58 views
2

假設我已經實現了索引器類型A,類型A是一個庫。現在我想擴展它的索引器,例如這裏我想將浮點數添加到索引器中。爲現有類別擴展索引器

我制定瞭如下代碼:

type A(a:int array) = 
    member this.Item 
    with get(x) = a.[x] 
    and set(x) value = a.[x] <- value 

type A with 
    member m.Item with 
    get(x:float) = m.[x |> int] 
    and set(x:float) v = m.[x |> int] <- v 

,但它似乎不工作:

let a = A([| 1;2;3 |]) 
a.[1] 
a.[1] <- 10 

a.[1.0] 

最後一行,我得到:

Script1.fsx(243,4): error FS0001: This expression was expected to have type 
    int  
but here has type 
    float  

是擴大索引可能在F#中?謝謝!

回答

2

我剛在FSI試過這個,它似乎工作。 你使用什麼編譯器? 這是我饋送到FSI什麼:

type A(a:int array) = 
    member this.Item 
    with get(x) = a.[x] 
    and set(x) value = a.[x] <- value 

type A with 
    member m.Item 
     with get(x:float) = m.[x |> int] 
     and set(x:float) v = m.[x |> int] <- v 

let a = A([| 1;2;3 |]) 
a.[1] <- 10 
printfn "%A" a.[1.2] 

此打印「10」

5

此行爲不同,當類型擴展在一個單獨的組件(或單獨的模塊)被定義,當它是在相同的模塊作爲類型定義。

  • 當兩者是相同的模塊中,F#編譯成一個單一類和Item成爲一個標準的重載索引 - 在這種情況下,你的代碼按預期工作(這是你如何實際寫在這裏) 。

  • 當它們位於不同的模塊中時,F#將索引器編譯爲擴展成員。在這種情況下,我收到了您描述的錯誤消息。

使用擴展成員(例如新方法)添加新的重載是可能的。據我所看到的,specificaton不說這不應該被用於索引工作,所以我認爲這是一個錯誤(你能在微軟COM報告給fsbugs?)

+0

尼斯抓,托馬斯! – 2011-03-08 11:26:32

+0

感謝Tomas!我發送了一封電子郵件給FSharp Bug Reports。 – 2011-03-08 12:04:34

0

錯誤描述說非常清楚 - 預計int,給定float,所以問題是1.0,如果你用1代替它,它應該工作。

1爲int

1.0是浮動

1.0F是FLOAT32,又名在一些語言一倍