代码之家  ›  专栏  ›  技术社区  ›  J. Doe

约束的typealias不使用约束

  •  0
  • J. Doe  · 技术社区  · 6 年前

    这工作:

    protocol Walkable {
        init()
    }
    
    class Animal {
        init(someProperty: Int) {}
    }
    
    class WalkableAnimal: Animal, Walkable {
        required init() {
            super.init(someProperty: 0)
        }
    }
    
    class Person {
        init() {
            InitializeAWalkableAnimal(walkableAnimal: WalkableAnimal.self)
        }
    
        func InitializeAWalkableAnimal<T: Animal>(walkableAnimal: T.Type) where T: Walkable {
            let animal = walkableAnimal.init()
        }
    }
    

    但是,我希望完全避免可行走动物子类。我只想创建一个 Cat class Animal 并符合 Walkable 协议。而且,我不能通过 直接作为参数,因为类型是动态的。我希望这样的事情能奏效:

    protocol Walkable {
        init()
    }
    
    class Animal {
        init(someProperty: Int) {}
    }
    
    class Cat: Animal, Walkable {
        required init() {
            super.init(someProperty: 0)
        }
    }
    
    class Dog: Animal, Walkable {
        required init() {
            super.init(someProperty: 1)
        }
    }
    
    typealias AnyWalkableAnimal = (Animal & Walkable).Type
    
    class Person {
        init(anyWalkableAnimal: AnyWalkableAnimal) {
            // ERROR
            InitializeAWalkableAnimal(walkableAnimal: anyWalkableAnimal.self)
        }
    
        func InitializeAWalkableAnimal<T: Animal>(walkableAnimal: T.Type) where T: Walkable {
            let animal = walkableAnimal.init()
        }
    }
    
    class PersonCaller {
        init() {
            Person(anyWalkableAnimal: Cat.self)
            Person(anyWalkableAnimal: Dog.self)
        }
    }
    

    错误是:

    实例方法“InitializeAwalkableAnimal(WalkableAnimal:)”需要 那个“动物”符合“可行走的”

    这是胡说,因为 typealias 不允许不允许 Walkables 正确的?为什么编译器不高兴?有什么方法可以让我绕过任何符合这两个条件的类型吗 动物 可步行的 ?为什么是 类型别名 不工作?这个 类型别名 明确地提到它所采用的类型必须是 动物 可步行的 . 它的工作方式与预期相反:当我试图通过 动物 不符合 可步行的 初始化器给出编译错误。

    如果有任何不同,我将于2018年12月25日在Swift开发工具链上进行开发。

    1 回复  |  直到 6 年前
        1
  •  2
  •   rob mayoff    6 年前

    我不明白为什么 InitializeAWalkableAnimal 必须是通用的。

    protocol Walkable {
        init()
    }
    
    class Animal {
        init(someProperty: Int) { }
    }
    
    class Cat: Animal, Walkable {
        required init() { super.init(someProperty: 0) }
    }
    
    class Dog: Animal, Walkable {
        required init() { super.init(someProperty: 1) }
    }
    
    typealias Pet = Animal & Walkable
    typealias PetType = Pet.Type
    
    class Person {
        init(petType: PetType) {
            initPet(petType: petType)
        }
    
        func initPet(petType: PetType) {
            let pet = petType.init()
            print("I got a pet: \(pet)")
        }
    }
    
    class PersonCaller {
        init() {
            Person(petType: Cat.self)
            Person(petType: Dog.self)
        }
    }
    
    _ = PersonCaller()
    

    输出:

    I got a pet: __lldb_expr_8.Cat
    I got a pet: __lldb_expr_8.Dog