泛型,即「參數化類型」。一提到參數,最熟悉的就是定義方法時有形參,而後調用此方法時傳遞實參。那麼參數化類型怎麼理解呢?顧名思義,就是將類型由原來的具體的類型參數化,相似於方法中的變量參數,此時類型也定義成參數形式(能夠稱之爲類型形參),而後在使用/調用時傳入具體的類型。 ——來自百度typescript
自我理解:泛型函數就是,你定義函數時候,是萬能類型。在調用的時候,只要你把具體的類型傳進去就好。好處呢,就是代碼的複用,減小代碼量。編程
在面向對象的語言中都是有泛型的這個概念和實現的。好比說:JAVA、C#、C++、TypeScript等等。數組
其實泛型是用的很普遍的,特別是在寫底層框架的時候。當你們去看源碼的時候,會看到不少泛型。最近的工做中也用到了泛型,算是寫底層吧,由於給別人調用。bash
工做需求是這樣的 ,使用TCP/IP協議,從客戶端發送 「結構體」到服務端。通常都是會將數據轉化成byte[],再進行數據的傳送。查資料和用泛型改造後:框架
C#代碼ide
// 結構體轉byte數組
public byte[] StructToBytes<T>(T structParams)
{
var size = Marshal.SizeOf(structParams);
var buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structParams, buffer, false);
var bytes = new byte[size];
Marshal.Copy(buffer, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
// 結構體轉byte數組
public static T BytesToStruct<T>(byte[] arr) where T : new()
{
// where後面的泛型約束:參數須要有一個無參的構造函數
T structType = new T();
var size = Marshal.SizeOf(structType);
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(arr, 0, ptr, size);
structType = (T)Marshal.PtrToStructure(ptr, structType.GetType());
Marshal.FreeHGlobal(ptr);
return structType;
}
複製代碼
public struct TestStruct0
{
public int count;
public string key;
}
public struct TestStruct1
{
public int count1;
public string key1;
}
// testStruct0 爲實例
StructToBytes<TestStruct0>(testStruct0)
// testStruct1 爲實例
StructToBytes<TestStruct1>(testStruct1)
複製代碼
在方法寫成泛型之後,不管結構體是什麼,函數只須要寫一遍。調用方只須要寫結構體的類型,和傳入相應的實例就能夠,而不須要寫多個函數。對於參數不同的而實現是同樣的函數,你們能夠考慮寫成泛型方法或者用接口。函數
由於泛型在多種面嚮對象語言中均有實現,爲了廣大水友能更好的理解,或者說消除語言方面的區別。接下來寫一個C#、JAVA、typescript的簡單泛型函數版本。ui
C#的泛型函數:spa
public void Test<T>(T params)
{
// TODO
}
// 調用實例1: Student爲類型,student爲傳入參數
Test<Student>(student);
// 調用實例2: String爲類型
Test<String>("我是參數")
// 調用實例3:Int爲類型
Test<Int>(100)
複製代碼
Java中沒有Struct,咱們將用簡單的例子:code
// 返回值爲T類型的實例
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
複製代碼
// 調用
test1 obj1 = genericMethod(Class.forName("com.test.test1"));
test2 obj2 = genericMethod(Class.forName("com.test.test2"));
複製代碼
TypeScript 泛型函數代碼
function identity<T>(arg: T): T {
return arg;
}
// 調用
let output0 Identity(3);
let output1 = identity("myString");
複製代碼
自我理解用法:泛型函數通常用在基礎類型的函數較多,像Int、String、struct,這種不能用接口限定的,用泛型去寫方法。若是是Object類型的話,能夠用接口是去限定參數。記得有一句話叫對接口編程,而不是對實現編程。