我可以在Swift中模拟traits/mixins吗?

Bil*_*ill 26 traits mixins swift

斯威夫特是否有一种混合特征的方式,斯卡拉?关于使用扩展来向现有类添加协议的Swift小册子的部分非常接近.但是,由于协议不能包含实现,因此不能将其用于将代码混合到类中.还有另外一种方法吗?

Jes*_*ssy 8

从Swift 2.0开始,是的!

提供默认实现

您可以使用协议扩展为该协议的任何方法或属性要求提供默认实现.如果符合类型提供其自己的必需方法或属性的实现,则将使用该实现而不是扩展提供的实现.


Bry*_*hen 7

模拟混合的一种方法是使用通用函数来提供实现

例如,使用这些协议

protocol Named {
    func GetName() -> String
}

protocol NamedExtension {
    func GetLowercaseName() -> String
    func GetUppercaseName() -> String
}
Run Code Online (Sandbox Code Playgroud)

我想要一些类来实现GetName()和使用混合所以他们也得到GetLowercaseName()GetUppercaseName()没有实现它们

这是NamedExtension在自由函数中的实现

func GetLowercaseNameImpl<T:Named>(obj:T) -> String {
    return obj.GetName().lowercaseString
}

func GetUppercaseNameImpl<T:Named>(obj:T) -> String {
    return obj.GetName().uppercaseString
}
Run Code Online (Sandbox Code Playgroud)

和扩展 Int

extension Int : Named {
    func GetName() -> String {
        return "Int"
    }
}

extension Int : NamedExtension {
    // use provided implementation
    func GetLowercaseName() -> String {
        return GetLowercaseNameImpl(self)
    }
    func GetUppercaseName() -> String {
        return GetUppercaseNameImpl(self)
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用

1.GetName() // result Int
1.GetUppercaseName() // result "INT"
1.GetLowercaseName() // result "int"
Run Code Online (Sandbox Code Playgroud)


Eri*_*rik 6

我不知道斯卡拉,但你告诉我它是什么,可以同时创建protocolextension扩展类型添加"伪特征"的行为.

例如:

protocol IsGreaterThan
{
    func isGreaterThan(other:Int) -> Bool
    func isNotGreaterThan(other:Int) -> Bool
}

extension Int : IsGreaterThan
{
    func isGreaterThan(other:Int) -> Bool
    {
        return self > other
    }

    func isNotGreaterThan(other:Int) -> Bool
    {
        return !isGreaterThan(other)
    }
}
Run Code Online (Sandbox Code Playgroud)

真正的腿筋是现在如何限制泛型.我认为他们将在即将到来的Swift版本中有所改进.

  • @sanz是的,但你必须重写你扩展的任何类的实现.一个特征系统(或类似的东西)会让我有一个名为`IntegerComparable`的类,它包含实现,可以简单地混合到其他类中.在你的系统下,我需要将方法体`isGreaterThan`和`isNotGreaterThan`复制到我想要扩展的每个类中,对吧? (5认同)