【问题标题】:swift program to interface快速程序接口
【发布时间】:2014-12-17 16:54:44
【问题描述】:

此处编写的 Car 和 Truck 类作为示例,但在编译时程序可能不知道它们。

可能还有更多种类的汽车尚不为人所知

例如,可能会有一个名为法拉利、兰博基尼的特殊级别,它可能会出现在系统不知道的道路上。

我们的目标是编程接口,而不是特定的实现

我们需要做以下类似的事情

  1. 创建实例var vehicle: IDrive = Vehicle()
  2. vehicle.drive()

我们尝试了一些技术,但如果不强制转换为特定实现就无法使其工作,需要一个独立的解决方案而不需要强制转换为特定实现。

也欢迎任何横向方法,也许我们的方法完全错误,但请记住函数 instantiateAndDrive 必须具有基于 protocol 的参数的约束

给负面选民(又称傻瓜)的注意事项:请提出问题以澄清它是否对您没有意义,或者去给自己买一本“​​白痴设计模式书”

    public protocol IDrive {
        func drive()
    }

    public class Car: IDrive {
        public init() {}
        public func drive() {}
    }

    class Truck: IDrive {
        public init() {}
        public func drive() {}
    }

class Test { //our attempts
   func instantiateAndDrive(Vehicle:IDrive.Type) {
       var vehicle = Vehicle()
       vehicle.drive()

   }

    func instantiateAndDrive2<T:IDrive>(Vehicle: T) {
        var vehicle = Vehicle()
        vehicle.drive()
    }
}

var test = Test()
test.instantiateAndDrive(Car.self)

编辑 - 在 AirSpeed Velocity 的回答之后尝试使用类

public protocol Drivable {
    init()
    func drive()
}

public class Car: Drivable {
    public required init() {}
    public func drive() { println("vroom") }
}

public class Truck: Drivable {
    public required init() {}

    public func drive() { println("brrrrrrm") }
}

class Test {
    func instantiateAndDrive(Vehicle:Drivable.Type) {
        var vehicle = Vehicle()
        vehicle.drive()
    }

    func instantiateAndDrive2<T:Drivable>(Vehicle: T) {
        ver vehicle = Vehicle()
        vehicle.drive()
    }
}
//var test = Test()
//test.instantiateAndDrive(Car.self)
//test.instantiateAndDrive(Truck.self)

【问题讨论】:

    标签: design-patterns swift protocols


    【解决方案1】:

    为了能够通用地创建泛型类型,您需要知道它支持初始化器。您可以通过在协议中添加init() 函数来做到这一点:

    public protocol Drivable {
        // enable drivable things to be
        // created with a  default initializer
        init()
    
        // (you could instead require a type implement
        // an initializer that took parameters)
    
        func drive()
    }
    

    然后您可以编写创建和操作它们的函数:

    struct Car: Drivable {
        init() { }
        func drive() { println("vroom") }
    }
    
    struct Truck: Drivable {
        init() { }
        func drive() { println("brrrrrrm") }
    }
    
    struct Test<D: Drivable> {
        func instantiateAndDrive() {
            // whatever D is, it implements init()
            let d = D()
            // and drive()
            d.drive()
        }
    }
    
    Test<Car>().instantiateAndDrive()
    Test<Truck>().instantiateAndDrive()
    

    尽管使用这种方法,当您说“Car 和 Truck 类在此处作为示例编写,但在编译时程序可能不知道它们”——上面的代码意味着它们不需要让程序知道在编译时执行测试。但它们确实需要在编译时为测试的调用者所知。

    当泛型函数返回一个类型时,这种方法更有用。例如,ExtensibleCollectionType 需要 init(),因此可以这样使用:

    func returnCollectionContainingOne<C: ExtensibleCollectionType where C.Generator.Element == Int>() -> C {
    
        // this is allowed because the ExtensibleCollectionType procol 
        // requires the type implement an init() that takes no parameters
        var result = C()
    
        // and it also defines an `append` function that allows you to do this:
        result.append(1)
    
        // note, the reason it was possible to give a "1" as the argument to
        // append was because of the "where C.Generator.Element == Int" part
        // of the generic placeholder constraint 
    
        return result
    }
    
    // now you can use returnCollectionContainingOne with arrays:
    let a: [Int] = returnCollectionContainingOne()
    
    // or with ContiguousArrays:
    let b: ContiguousArray = returnCollectionContainingOne()
    

    【讨论】:

    • 真棒大师...你懂的东西,我们可以通过课程来完成这项工作吗?还是仅通过结构?
    • 我已经用建议的方法编辑了我的问题,但尝试使用类,你能帮我吗
    • Airspeed,感谢您的尝试,我确实同意了,但实际上我还没有到那里,但我在此过程中学到了一些东西... :) 这是我的另一次尝试,请检查@ 987654321@
    • 最后一个问题,这是我真正需要最终完成的,请分享您对这个问题的想法,stackoverflow.com/questions/27571465/generic-types-collection
    【解决方案2】:

    您想使用Self。在协议中,它的意思是“实际采用我的类型”。在类的方法中,表示“实际调用该方法的类”。

    【讨论】:

    • 我们已经完成了使用 .self,但遇到了仍然需要转换为我们不想要的特定实现的问题。请在操场上尝试,如果您能提供可行的解决方案,我们将不胜感激
    • Self 不是 self
    • hmmmm 这对我来说是新的,你能帮忙解决一下代码还是参考一些文档来解决它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多