当将实现结构分配给键入为var
的变量时,使用let
和protocol
实现属性的行为会有所不同。
protocol Req {
var path: String? { get }
}
extension Req {
var path: String? { return "Req" }
}
struct LetReq: Req {
let path = "LetReq"
}
struct VarReq: Req {
var path: String? { return "VarReq" }
}
var req: Req!
req = VarReq()
req.path // prints "VarReq"
req = LetReq()
req.path // prints "Req" not "LetReq" which seems very awkward.
这是Swift设计的行为吗?
答案 0 :(得分:1)
我认为这是一个编译错误。如果您将LetReq
作为可选字符串,它将按预期工作:
struct LetReq: Req {
let path: String? = "LetReq"
}
File a bug与Apple合作。
答案 1 :(得分:0)
我认为这种行为是正确的。
struct LetReq: Req {
let path = "LetReq"
}
路径String
类型不是String?
var req: Req!
req = LetReq()
req.path
req
是Req
的类型。因此,req.path
表示类型为String?
,名称为path
Req
的扩展程序具有path
变量的默认变量。因此req.path
引用的变量不是LetReq
的{{1}}
答案 2 :(得分:0)
它含糊不清......但我会赌一个错误。
至少对于当前的实施(<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var crudServiceBaseUrl = "http://localhost:49885/api",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/Suppliers",
dataType: "json",
type: "Get"
},
update: {
url: function(data) {
debugger;
//return crudServiceBaseUrl + "/Suppliers/" + JSON.stringify(data.models[0]);
return crudServiceBaseUrl + "/Suppliers";
},
dataType: "json",
type: "Put",
contentType: "application/json"
},
destroy: {
url: function(data) {
debugger;
return crudServiceBaseUrl + "/Suppliers/" + JSON.stringify(data.SupplierId);
//return crudServiceBaseUrl + "/Suppliers";
},
//url: crudServiceBaseUrl + "/Suppliers",
dataType: "json",
type: "Delete",
contentType: "application/json"
},
create: {
url: function (data) {
debugger;
//return crudServiceBaseUrl + "/Suppliers/" + JSON.stringify(data);
return crudServiceBaseUrl + "/Suppliers";
},
//url: crudServiceBaseUrl + "/Suppliers",
dataType: "json",
type: "Post",
contentType: "application/json",
//data: JSON.stringify([data.SupplierId, data.CommId])
},
parameterMap: function(options, operation) {
debugger;
if (operation !== "read" && options) {
return { models: JSON.stringify(options) };
}
}
},
batch: false,
pageSize: 20,
schema: {
data: function(data) { //specify the array that contains the data
return data || [];
},
errors: function(response) {
return response.error;
},
model: {
id: "SupplierId",
fields: {
SupplierId: { validation: { required: true } },
CommId: { validation: { required: true } },
EmailId: { validation: { required: true } },
FullName: { validation: { required: true } },
FirstName: { validation: { required: true } },
Description: { validation: { required: true } },
LastName: { validation: { required: true } },
StateId: { validation: { required: true } }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
sortable: true,
height: 550,
toolbar: ["create", "save", "cancel"],
columns: [
"SupplierId",
{ field: "SupplierId", title: "SupplierId", width: 120 },
{ field: "CommId", title: "CommId", width: 120 },
{ field: "EmailId", title: "EmailId", width: 120 },
{ field: "FullName", width: 120 },
{ field: "FirstName", width: 120 },
{ field: "Description", width: 120 },
{ field: "LastName", width: 120 },
{ field: "StateId", width: 120 },
{ command: "destroy", title: " ", width: 150 }
],
editable: true
});
});
</script>
<div id="example">
<div id="grid"></div>
</div>
2.2);
这可以通过这证明。
swiftc
但无论如何,编译器似乎没有通过协议扩展来检查这种重新声明。因此,struct AA {
func a() -> String { return "" }
func a() -> String? { return "" }
var b: String { return "" }
var b: String? { return "" } // Error: Invalid redeclaraion of `b`.
}
实例实际上提供了两个属性。
LetReq
你可以用这个来检查。
var path: String { get }
var path: String? { get }
我相信编译器必须防止这种属性重载。出于同样的原因,他们在print(LetReq().path as String?) // prints `Optional("Req")`.
print(LetReq().path as String) // prints `LetReq`.
中阻止了财产超载。所以,我认为这是一个错误。