创建从多个协议继承的协议类型的对象时出错

时间:2016-06-01 19:01:44

标签: swift swift-protocols

在以下代码中,有3个协议:WheeledVehicleWheeledVehicle(继承自WheeledVehicle

protocol Wheeled {
    var numberOfWheels: Int { get }
}

protocol Vehicle {
    var maker: String { get }
    var owner: String {get set}
    var ownerKid: String { get }
}

protocol WheeledVehicle: Wheeled, Vehicle {
  // simply just combine Wheeled and Vehicle
}

class Bike: Vehicle, Wheeled {
let numberOfWheels: Int = 0
var ownerKid: String = "Junior"

var maker: String {
    return "Ford"
}

var owner: String {
    get {
        return "Bob"
        }
        set {
            ownerKid = "\(newValue) Junior"
        }
    }
}


let bike: Bike = Bike()

let wheeledVehicleBike: WheeledVehicle = bike //error: value of type 'Bike' does not conform to specified type 'WheeledVehicle'

问题:错误本身,我不明白,为什么类型Bike的值不符合指定的类型WheeledVehicle

非常感谢你的时间和帮助。

3 个答案:

答案 0 :(得分:3)

基本上:因为它不符合

要让编译器知道 for ($row = $this->startFrom; $row <= $highestRow; $row++) { if ($rowMatrix == $chunksize) { // $job = (new importExcelInsert($matrixContacts, $matrixDefaultFields, $matrixCustomFields, $this->idCompany))->delay($jobDelay)->onQueue('excelInserts'); // var_dump($matrixContacts); $job = (new importExcelInsert($matrixContacts, $matrixDefaultFields, $matrixCustomFields, $this->idCompany, $rowMatrix))->delay($jobDelay)->onQueue('excelInserts'); $this->dispatch($job); $njobs++; $matrixContacts = []; $matrixDefaultFields = []; $matrixCustomFields = []; $rowMatrix = 0; } $userEmail = $sheet->getCellByColumnAndRow($posEmail, $row)->getValue(); if ($userEmail == '' || !filter_var($userEmail, FILTER_VALIDATE_EMAIL)) { $error++; } else if (Contact::where('email', '=', $userEmail)->where('id_contact_list', '=', $this->idList)->count()) { $ignored++; } else { // $uuid = Uuid::generate(4); $matrixContacts[$rowMatrix][1] = $this->idList; //CONTACT_LIST_ID $matrixContacts[$rowMatrix][2] = $sheet->getCellByColumnAndRow($posNome, $row)->getValue(); //Name $matrixContacts[$rowMatrix][3] = $userEmail; //Email $matrixContacts[$rowMatrix][4] = $unsubCode; //Unsubscribe Code $vecFieldId = []; $vecValues = []; $i = 0; if (!$this->arrayDefaultFields[0] == null) { for ($j = 0; $j < sizeof($this->arrayDefaultFields); $j += 2) { $vecFieldId[$i] = $this->arrayDefaultFields[$j]; $vecValues[$i] = $sheet->getCellByColumnAndRow($this->arrayDefaultFields[$j + 1], $row)->getValue(); $i++; } $matrixDefaultFields[$rowMatrix][0] = $vecFieldId; $matrixDefaultFields[$rowMatrix][1] = $vecValues; } $i = 0; if (!$this->arrayCustomFields[0] == null) { for ($j = 0; $j < sizeof($this->arrayCustomFields); $j += 2) { $vecFieldId[$i] = $this->arrayCustomFields[$j]; $vecValues[$i] = $sheet->getCellByColumnAndRow($this->arrayCustomFields[$j + 1], $row)->getValue(); $i++; } $matrixCustomFields[$rowMatrix][0] = $vecFieldId; $matrixCustomFields[$rowMatrix][1] = $vecValues; } $rowMatrix++; } } if (!empty($matrixContacts)) { $job = (new importExcelInsert($matrixContacts, $matrixDefaultFields, $matrixCustomFields, $this->idCompany, $rowMatrix + 1))->delay($jobDelay)->onQueue('excelInserts'); $this->dispatch($job); $njobs++; } 符合Bike,您必须指定它。编译器不会只是假设两者都符合相同的协议,它们可以互相分配。

以下方法不起作用。

WheeledVehicle

甚至更简单

class A { var a : String = "" }
class B { var a : String = "" }

var a : A = A()
var b : B = a // cannot convert value of type 'A' to specified type 'B'

编译器不关心这两种类型 - 它们必须相似

如果class A { } class B { } var a : A = A() var b : B = a // cannot convert value of type 'A' to specified type 'B' 添加了WheeledVehicle,您的示例会发生什么? func不再符合它吗?

Bike符合Bike唯一方法是明确声明:WheeledVehicle

答案 1 :(得分:3)

继承仅适用于一个方向。例如,如果Cat继承自Animal,则Cat的实例是Animal的实例。但Animal的实例不一定是Cat

同样,在您的示例中,WheeledVehicle的实例既是Wheeled的实例,也是Vehicle的实例。但是,WheeledVehicle的实例都不一定是WheeledVehicle的实例。

另一个注意事项:您可能会发现在代码中使用此表示法很方便:

let wheeledVehicleBike: protocol<Wheeled, Vehicle> = bike

这允许您指定类型符合的多个协议,而无需为此目的定义其他协议。

答案 2 :(得分:2)

编译器并不认为“轮到”和“作为车辆”意味着“成为轮式车辆”。可能是您的WheeledVehicle添加了新要求。

目前,编译器不会执行此类检查。老实说,它不应该因为这引入了许多不明确的,隐含的行为而没有什么好处。

您必须明确将Bike改为WheeledVehicle