
|Swift|C++
:-:|:-:|:-:
有用的關(guān)鍵字和符號|<>, where|template,<>
先來介紹 Swift 的泛型.
Swift 中在尖括號里寫一個名字來創(chuàng)建一個泛型函數(shù)或者類型:
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
var result = [Item]()
for _ in 0..<numberOfTimes {
result.append(item)
}
return result
}
makeArray(repeating: "knock", numberOfTimes:4)
你可以創(chuàng)建泛型函數(shù), 方法, 類, 枚舉和結(jié)構(gòu)體:
enum OptionalValue<Wrapped> {
case none
case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)
在類型名后面使用where來指定對類型的特殊需求, 比如, 限定類型實現(xiàn)某一個協(xié)議, 限定兩個類型是相同的,或者限定某個類必須有一個特定的父類:
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Bool
where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element {
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
}
}
}
return false
}
anyCommonElements([1, 2, 3], [3])
練習: 修改
anyCommonElements(_:_:)函數(shù)來創(chuàng)建一個函數(shù),返回一個數(shù)組,內(nèi)容是兩個序列的共有元素。
注意, <T: Equatable>和 <T where T: Equatable>是等價的.
** C++中**的泛型分為泛型函數(shù)和泛型類. 通過創(chuàng)建相應(yīng)的模板實現(xiàn): 函數(shù)模板和類模板.
類模板, 以 template開頭, 尖括號中寫類型參數(shù)名列表, 類型參數(shù)名以 class或typename開頭, 再后面寫類的定義:
#include <iostream>
using namespace std;
template <typename T>
class Class1 {
public:
T doSomething(const T);
T t;
};
int main() {
Class1<int> class1;
Class1<double> class2;
return 0;
}
函數(shù)模板,和類模板類似:
#include <iostream>
using namespace std;
template <typename T>
void doSomething(T t) {
cout << t+1 << endl;
}
int main() {
doSomething(5);
return 0;
}
注意到, 在使用函數(shù)模板的時候, 和使用一般函數(shù)一樣doSomething(5);, 而使用類模板時候需要顯式指定類型實參Class<int> class1;.
這是因為當我們使用函數(shù)模板來調(diào)用某一個具體的函數(shù)時, 編譯器將為我們自動推斷出模板參數(shù),比如doSomething(5); 編譯器將推斷出類型參數(shù)T 為int.
而使用類模板的時候, 就沒有這樣方便了, 我們必須在使用類模板的時候需要顯式的指定模板實參.
另外在定義模板(不管是函數(shù)模板還是類模板)時, 尖括號中的模板參數(shù)列表,并非必須是需要class 或typename開頭標示的某一類型, 它們也可以是確定的類型,比如template<int N> ...:
#include <iostream>
using namespace std;
template <int T>
void doSomething() {
cout << T << endl;
}
template <const char ch>
class Class {
public:
void doSomething() {
cout << ch << endl;
}
};
int main() {
doSomething<5>();
Class<'k'> class1;
class1.doSomething();
return 0;
}
不過, 此時在使用模板的時候,尖括號的內(nèi)容必須用常量表達式來提供給模板.