Any于AnyObject在Swift代码中经常看到,二者都用来表示类型的随意性(OC中有id),那么二者有什么区别呢?
概括上来说AnyObject用于任何类(class)的实例,而Any可以用于表示任何类型,包括基本类型、值类型以及实例
从这个意义上来说,AnyObject是Any的子集
比如:Swift中的enum、struct(Array,Dictioanry)都属于值类型,因此不能使用AnyObject来修饰
通过下面的代码将对Any与AnyObject有更清晰的理解
class LTCarClass{} //类
struct LTCarStruct{} //结构体
1、Any测试代码
定义一个Any类型的数组,试着在数组中添加各种类型的数据
var arrAny = [Any]()
arrAny.append(1) //添加基本类型,正常
arrAny.append(1.0)
arrAny.append("TOTTI") //添加字符串,正常
arrAny.append(LTCarClass()) //添加实例对象,正常
arrAny.append(LTCarStruct()) //添加结构体,正常
2、AnyObject测试代码
同样的定义一个AnyObject类型的数组,试着在数组中添加各种类型的数据
var arrAnyObject = [AnyObject]()
arrAnyObject.append(1)
//报错:Argument type 'Int' expected to be an instance of a class or class-constrained type
arrAnyObject.append("TOTTI")
//报错:Argument type 'String' expected to be an instance of a class or class-constrained type
arrAnyObject.append(LTCarStruct())
//报错:Argument type 'LTCarStruct' expected to be an instance of a class or class-constrained type
arrAnyObject.append(LTCarClass()) //正常
按照上面的结论,Any可以表示任何的变量,而在AnyObject的例子中,由于只有LTCarClass是一个类,而LTCarStruct是一个结构体,所以添加LTCarClass实例成功,而添加LTCarStruct时报错
泛型
通常,泛型为类或者方法提供一个类型参数,以便某个参数类型保持前后的一致性
func ltGeneric<T>(x: T, y: Int) -> T{
}
上述方法ltGeneric接受某个类型的参数x和一个Int类型的参数y,最后返回一个T类型。
这里的泛型T泛指任何类型。此处使用泛型主要有两点作用
1、保证了参数x类型的随意性
2、保证了参数x类型与整个方法的返回类型统一性
func ltMultiGeneric<T,U,Element>(x: T, y: U, z: Element) -> Void{
}
一个方法或者类型里面也可以有多个泛型,T,U等字母或者单词都可以,没具体限制
func ltAny(x:Any: y: Int) ->Any{
return nil
}
Any也可以表示参数的随意性,所以看上面代码,如果将x的类型修改为Any,返回类型也修改为类型,也是可以的。但是与ltGeneric方法中使用T来表示参数的随意性有什么区别呢?
区别:
ltGeneric中的参数x的类型与方法的返回类型时一致的,而ltAny中却没有这个特性(参数x与返回类型可以是任意类型,可以没有任何关系,不一定相同)
综上所述,应该尽量多使用泛型少用Any,避免转换类型是发生的类型错误
网友评论