在以下代码中,有3个协议:Wheeled
,Vehicle
和WheeledVehicle
(继承自Wheeled
和Vehicle
)
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
非常感谢你的时间和帮助。
答案 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
的实例。但是,Wheeled
和Vehicle
的实例都不一定是WheeledVehicle
的实例。
另一个注意事项:您可能会发现在代码中使用此表示法很方便:
let wheeledVehicleBike: protocol<Wheeled, Vehicle> = bike
这允许您指定类型符合的多个协议,而无需为此目的定义其他协议。
答案 2 :(得分:2)
编译器并不认为“轮到”和“作为车辆”意味着“成为轮式车辆”。可能是您的WheeledVehicle
添加了新要求。
目前,编译器不会执行此类检查。老实说,它不应该因为这引入了许多不明确的,隐含的行为而没有什么好处。
您必须明确将Bike
改为WheeledVehicle