swift泛型约束,swift种什么是泛型泛型用来解决什么

1,swift种什么是泛型泛型用来解决什么泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类型 。它的可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图例如,Swift 的数组和字典类型都是泛型集 。你可以创建一个Int数组 , 也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组 。同样的,你也可以创建存储任何指定类型的字典(dictionary),而且这些类型可以是没有限制的 。搜一下:swift种什么是泛型,泛型用来解决什么【swift泛型约束,swift种什么是泛型泛型用来解决什么】
2,swift泛型协议在函数中做参数和返回值泛型协议在函数中作为参数和返回值类型使用泛型协议只能作为泛型的约束使用,不能直接作为函数参数或者返回值类型使用 。就是说,函数要使用泛型协议作为类型,只能转换一下: 在函数中添加一个泛型,让泛型协议作为这个泛型的约束,然后就可以使用了 。如下:在makeASuperMan函数中, S为泛型, SupermanType为泛型协议 。SupermanType还只能作为泛型约束,不能作为参数类型 。
3,VS泛型约束可以参考一下信息:where T: struct类型参数必须为值类型 。where T : class类型参数必须为类型 。where T : new()类型参数必须有一个公有、无参的构造函数 。当于其它约束联合使用时,new()约束必须放在最后 。where T : 类型参数必须是指定的基类型或是派生自指定的基类型 。where T : 类型参数必须是指定的接口或是指定接口的实现 。可以指定多个接口约束 。接口约束也可以是泛型的 。至于你的第一个问题,T就是传入的类型啊 , 这样可以防止类型污染,你之前是java,对arraylist的使用应该很熟悉才对,道理是一样的,多逛逛类似的博客 , 对你有很大的帮助搜一下:VS泛型约束
4,swift的泛型协议为什么不用T语法swift中的协议(protocol)采用的是“Associated Types”的方式来实现泛型功能的,通过associatedtype关键字来声明一个类型的占位符作为协议定义的一部分 。swift的协议不支持下面的定义方式:protocol GeneratorType public mutating func next() -> Element?}而是应该使用这样的定义方式:protocol GeneratorType associatedtype Elementpublic mutating func next() -> Self.Element?}在swift中 , class、struct、enums都可以是用参数化类型来表达泛型的,只有在协议中需要使用associatedtype关键字来表达参数化类型 。为什么协议不采用这样的语法形式呢?我查看了很多讨论,原因大概总结为一下两点:采用语法的参数化方式的泛型其实定义了整个类型的家族 , 在概念上这对于一个可以具体实现的类型(class、struct、enums)是有意义的,比方说Array,Array 。但对于协议来说,协议表达的含义是single的 。你只会实现一次GeneratorType,而不会实现一个GeneratorType协议,接着又实现另外一个GeneratorType协议 。协议在swift中有两个目的,第一个目的是用来实现多继承(swift语言被设计为单继承的) , 第二个目的是强制实现者必须准守自己所指定的泛型约束 。关键字associatedtype是用来实现第二个目的的 。在GeneratorType中由associatedtype指定的Element,是用来控制next()方法的返回类型的 。而不是用来指定GeneratorType的类型的 。我们可以用一个例子进一步解释一下第二个观点public protocol Automobile associatedtype FuelTypeassociatedtype ExhaustTypefunc drive(fuel: FuelType) -> ExhaustType}public protocol Fuel associatedtype ExhaustTypefunc consume() -> ExhaustType}public protocol Exhaust init()func emit()}我们定义了三个协议,机动车(Automobile)、燃料(Fuel)、尾气(Exhaust),因为Automobile涉及到燃料和尾气所以它内定义了两个关联类型FuelType和ExhaustType , Fuel燃烧后会排放Exhaust,所以在Fuel内定义了关联类型ExhaustType 。而Exhaust不需要关联类型 。接下来我们做三个具体的实现:public struct UnleadedGasoline: Fuel public func consume() -> E print("...consuming unleaded gas...")return E()}}public struct CleanExhaust: Exhaust public init() public func emit() print("...this is some clean exhaust...")}}public class Car: Automobile public func drive(fuel: F) -> E return fuel.consume()}}我们重点关注Car的定义,我们之所以在Car的定义中同时使用了两种占位符F和E , 就是为了给这两个占位符所代表的类型增加约束,因为我们使用一种燃料,必然要排放这种燃料所对应的尾气 。于是我们这样使用Carvar car = Car<UnleadedGasoline, CleanExhaust>()car.drive(UnleadedGasoline()).emit()Car<UnleadedGasoline, CleanExhaust>在这里成为了一种具体的类型,从Car的意义上来看,燃料成为Car类型的一部分是无可厚非的,因为汽车本身就是可以用燃料进行类型区分的吗 。但尾气成为Car类型的一部分真的有意义吗?从现实生活当中看,这是没有意义,因为尾气一定尊属与某种燃料类型,用燃料做为类型的一部分已经足够了 。尾气成为类型的一部分问题出在了 , 我们需要在技术上进行泛型约束 。我们现在来调整一下Car的实现部分 。public class Car: Automobile public func drive(fuel: F) -> F.ExhaustType return fuel.consume()}}在新的定义中,我们把E从参数中去掉,而是换作为drive方法的返回值 。这样的效果是非常明显的,因为E的存在就是为了泛型约束 , 让其作为返回值是完全可以实现这种约束 。而且有没有使其成为类型一部分的副作用 。我们现在就可以这样获得一个Car的实例了 。var fusion = Car<UnleadedGasoline>()5,C泛型 类型约束要T是继承于Awhere T: A要T继承于B的where T: B在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制 。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误 。这些限制称为约束 。约束是使用 where 上下文关键字指定的 。下表列出了六种类型的约束:约束 说明T:结构 类型参数必须是值类型 。可以指定除 Nullable 以外的任何值类型 。有关更多信息,请参见使用可以为 null 的类型(C# 编程指南) 。T:类 类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型 。T:new() 类型参数必须具有无参数的公共构造函数 。当与其他约束一起使用时 , new() 约束必须最后指定 。T:&lt;基类名&gt; 类型参数必须是指定的基类或派生自指定的基类 。T:&lt;接口名称&gt; 类型参数必须是指定的接口或实现指定的接口 。可以指定多个接口约束 。约束接口也可以是泛型的 。T:U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数 。这称为裸类型约束 。//---------------------------------补充,由于泛型约束表达式全部是“AND”关系,所以不可能表示出“或”关系来,而且C#不支持多重继承 , 所以楼主的 , 这种或继承自A,或继承自B的需求,是无法实现的 。6,c 泛型约束的问题你这样写就是两个Default,没错的如果你想变成Chinese Amrican,可以这样public class PrintNationality<T> where T : INationality, new()T item = new T();public PrintNationality()((INationality)item).Nationality = typeof(T).Name;}public void Print()Console.WriteLine(string.Format("Nationality:}}如果有两个实现,子类不应该是那样的写法吧?比如 Chinese,属性应该是publicstring Nationalityset_Nationality = “Chinese”; } }吧?不然中国人和美国人两个实现类有什么区别?还用分国籍吗?你又没有给Chinese和American这两个对象的Nationality属性赋值 , 当然答案是Default Default如果是这样的话自然就不一样了 。publicclass Programstaticvoid Main(string[] args)PrintNationality<Chinese> _c = new PrintNationality<Chinese>(); PrintNationality<American> _a = new PrintNationality<American>();_c.Nationality="Chinese";_a.Nationality="American";_c.Print();_a.Print();}要t是继承于awhere t: a要t继承于b的where t: b在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制 。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误 。这些限制称为约束 。约束是使用 where 上下文关键字指定的 。下表列出了六种类型的约束:约束说明t:结构类型参数必须是值类型 。可以指定除 nullable 以外的任何值类型 。有关更多信息,请参见使用可以为 null 的类型(c# 编程指南) 。t:类类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型 。t:new()类型参数必须具有无参数的公共构造函数 。当与其他约束一起使用时,new() 约束必须最后指定 。t:<基类名>类型参数必须是指定的基类或派生自指定的基类 。t:<接口名称>类型参数必须是指定的接口或实现指定的接口 。可以指定多个接口约束 。约束接口也可以是泛型的 。t:u为 t 提供的类型参数必须是为 u 提供的参数或派生自为 u 提供的参数 。这称为裸类型约束 。//---------------------------------补充 , 由于泛型约束表达式全部是“and”关系,所以不可能表示出“或”关系来,而且c#不支持多重继承,所以楼主的,这种或继承自a,或继承自b的需求 , 是无法实现的 。