func inspect <SomeType> (value: SomeType) {
print ("Received \(type(of: value)) with the value of \(value)")
}
我正在关注Pro Swift书中的教程,但我无法理解为什么我们需要<SomeType>
。这似乎没必要。我们给编译器添加了哪些信息?
作者自己说:
注意使用SomeType:直接在尖括号中有一个 函数名称,以及描述value参数的名称。首先 尖括号中的一个是最重要的,因为它定义了 你的占位符数据类型:inspect()表示“有一个 名为inspect()的函数,可以与任何类型的数据类型一起使用, 但无论使用什么数据类型,我都想将其称为 SomeType。“所以,参数值:SomeType现在应该更多 sense:SomeType将被替换为用于的任何数据类型 调用函数。
我不理解占位符数据类型意味着什么?
修改
或者用更好的例子
func inspect <T> (value1: T, value2: T) {
// ....
}
我的问题:我知道T会强制执行value1&amp; value2具有相同的类型,因此<T>
的用例是什么。
答案 0 :(得分:4)
我们为编译器提供了哪些附加信息
我们说:&#34;亲爱的编译器:我现在不打算告诉你value
的类型是什么,这在宣布一个函数时似乎是不寻常的事情。但是相信我,编译器,你会知道当你看到这个函数如何被调用时它是什么类型的,在这个程序的其他地方。&#34;
答案 1 :(得分:3)
这可能令人困惑,因为该功能不是泛型的一个很好的例子。该函数可以重写为非泛型函数,但仍然完全相同:
func inspect (value: Any) {
print ("Received \(type(of: value)) with the value of \(value)")
}
在其他情况下,它们变得更有用。例如,如果它像
那样func inspect <T> (value1: T, value2: T) {
// ....
}
告诉编译器T
可以是任何类型,但两个参数必须是相同类型。如果您在此处使用过Any
,则参数可以是任何类型,并且可以是不同类型。
或者
func inspect <T> (value:T) -> T {
// ....
}
这表示该函数接受任何类型的参数并返回相同类型的。同样,如果您在此使用Any
,则声明不要求返回类型与参数类型匹配。
答案 2 :(得分:3)
赞同所提供的答案。
我们只是说你编写了如下代码(没有 <p-pickList [source]="data['brandList']" [target]="data['modelList']" [responsive]="true"
dragdrop="true">
<ng-template let-brandList pTemplate="item">
<div style="position: relative;height: 29px;top: 7px;">
<table style="margin: 5px;text-align: center;position: relative;bottom: 14px;font-size: 13px;right: 4px;">
<tr style="border-bottom: 1px solid #d3d5d8">
<td style="border-right: 1px solid #d3d5d8">
<span>{{brandList.productClass}}</span>
</td>
<td style="border-right: 1px solid #d3d5d8">
<span title="{{brandList.model}}" style="display: inline-block;width: 69px;white-space: nowrap;overflow: hidden !important;text-overflow: ellipsis;top: 3px;position: relative;">{{brandList.model}}</span>
</td>
<td style="border-right: 1px solid #d3d5d8">
<span>{{(brandList.brand).trim()}}</span>
</td>
</tr>
</table>
</div>
</ng-template>
</p-pickList>
),看看会发生什么:
<T>
这里func inspect (value1: T, value2: T) {
// some operation with value1, value2
}
的类型是什么? T
类是结构还是枚举?或者它是你想要的通用类型? 编译器不知道。它会给出以下错误:
错误:使用未声明的类型&#39; T&#39;
仅仅因为你用T
写了一些东西,它不会神奇地变成一个通用的东西。
为了更好地说明问题,请参阅此代码段:
T
func inspect (value1: T, value2: T) {
// some operation with value1, value2
var x = T()
var m = U()
}
class T {
var name = "someName"
}
class U {
var name = "someName"
}
&lt; - 您希望这是类var x = T()
的实例还是泛型?
如果没有T
,<T>
预期将成为x
类型的实例。如果您还没有将T
定义为某种类型,如果没有,那么您只会收到错误消息。
这就是您使用T
看到的实际代码中的原因。实际类型将进入&#39;类型<T>
是&#39;持有&#39;以前。 :
T
实际上执行func inspect <T> (value1: T, value2: T) {
// some operation with value1, value2
var x = T() // error!
var m = U() // No error
}
class T {
var name = "someName"
}
class U {
var name = "someName"
}
会产生错误:
&#39; T&#39;无法构造,因为它没有可访问的初始值设定项
如果编译器没有发现这个错误,那么函数内部的x = T()
将是非泛型的,并且会来自类定义或只是未知......
我们T
的原因是创建一个本地香草类型,避免来自外部的错误期望。 (虽然如果你限制它,那么它会有所不同)
为什么Swift取代泛型 <T>
而 class T
?我假设它是因为Swift优先考虑本地范围。