有沒有辦法在Ruby中實現mixin或者F#中的Scala特徵?mixin或F#中的特徵
我想要的是基本上將一個模塊複製到另一個模塊,以便它共享其他模塊的功能,但關閉修改。或者,考慮它的OOP方式,除了不能修改父對象之外,我想要多重繼承。
有沒有辦法在Ruby中實現mixin或者F#中的Scala特徵?mixin或F#中的特徵
我想要的是基本上將一個模塊複製到另一個模塊,以便它共享其他模塊的功能,但關閉修改。或者,考慮它的OOP方式,除了不能修改父對象之外,我想要多重繼承。
可以濫用inline
和成員的制約做鴨打字,這爲您帶來了mixins的一些好處。例如,你可以把這種Ruby代碼(從this tutorial拍攝):
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"
這樣:
type Phonograph(id, name) =
member x.Id : int = id
override x.ToString() = name
type EightTrack(id, name) =
member x.Id : int = id
override x.ToString() = name
module Debug =
let inline whoAmI x =
sprintf "%s (%d) : %s"
(^T : (member GetType : unit -> Type) x).Name
(^T : (member Id : int with get) x)
(^T : (member ToString : unit -> string) x)
let ph = Phonograph(537766170, "West End Blues")
let et = EightTrack(537765860, "Surrealistic Pillow")
Debug.whoAmI ph //"Phonograph (537766170) : West End Blues"
Debug.whoAmI et //"EightTrack (537765860) : Surrealistic Pillow"
它擁有超過不需要一個擴展方法的(有爭議的)優勢公共基類或接口。關於您之前關於open
關鍵字的問題,您可能會有幾個模塊定義whoAmI
,最後一個模塊會影響以前的模塊。這樣你就可以「混合」你想要的模塊。 F#核心庫使用與checked operators類似的方法。
在.NET框架中,最好使用擴展方法(類型擴展)模擬Ruby mixins。我不相信F#具有更接近mixin,traits或多重繼承的特殊語言特徵。
看到這個問題:How do I create an extension method (F#)?
而且這樣的描述:http://msdn.microsoft.com/en-us/library/dd233211.aspx
對於速度的緣故,這裏的MSDN上給出的例子:
module MyModule1 =
// Define a type.
type MyClass() =
member this.F() = 100
// Define type extension.
type MyClass with
member this.G() = 200
module MyModule2 =
let function1 (obj1: MyModule1.MyClass) =
// Call an ordinary method.
printfn "%d" (obj1.F())
// Call the extension method.
printfn "%d" (obj1.G())
有點相關:http://stackoverflow.com/q/1805473/162396 – Daniel 2012-07-13 18:32:09