用Swift在数组中存储不同类型的值

时间:2022-10-26 17:02:47

In Swift Programming Language, it says "An array stores multiple values of the same type in an ordered list." But I have found that you can store multiple types of values in the array. Is the description incorrect?

在Swift编程语言中,它表示“数组在有序列表中存储相同类型的多个值”。但是我发现可以在数组中存储多种类型的值。描述是不正确的?

e.g.

如。

var test = ["a", "b", true, "hi", 1]

5 个解决方案

#1


17  

From REPL

从REPL

 xcrun swift
  1> import Foundation
  2> var test = ["a", "b", true, "hi", 1]
test: __NSArrayI = @"5 objects" {
  [0] = "a"
  [1] = "b"
  [2] =
  [3] = "hi"
  [4] = (long)1
}
  3>

you can see test is NSArray, which is kind of AnyObject[] or NSObject[]

可以看到test是NSArray,它是AnyObject[]或NSObject[]

What happening is that Foundation provides the ability to convert number and boolean into NSNumber. Compiler will perform the conversion whenever required to make code compile.

Foundation提供了将数字和布尔值转换为NSNumber的能力。编译器将在需要时执行转换,以使代码编译。

So they now have common type of NSObject and therefore inferred as NSArray

所以他们现在有了普通的NSObject类型因此推断为NSArray


Your code doesn't compile in REPL without import Foundation.

如果没有导入基础,您的代码不会在REPL中编译。

 var test = ["a", "b", true, "hi", 1]
<REPL>:1:12: error: cannot convert the expression's type 'Array' to type 'ArrayLiteralConvertible'

 var test:Array = ["a", "b", true, "hi", 1]
<REPL>:4:18: error: cannot convert the expression's type 'Array' to type 'ExtendedGraphemeClusterLiteralConvertible'

but you can do this

但你可以这样做。

var test : Any[] = ["a", "b", true, "hi", 1]

Because they have a common type, which is Any.

因为它们有一个共同的类型,也就是任何一个。


Note: AnyObject[] won't work without import Foundation.

注意:AnyObject[]在没有导入基础的情况下无法工作。

var test:AnyObject[] = ["a", "b", true, "hi", 1]
<REPL>:2:24: error: type 'Bool' does not conform to protocol 'AnyObject'

#2


3  

To initialize an Array with arbitrary types, just use var arbitraryArray = [Any]().

要初始化具有任意类型的数组,只需使用var仲裁数组= [Any]()。

#3


2  

AnyObject is a type and you can create an array that holds those, which (as the class name implies) means it can hold any type of object. NSArrays aren't type-bound and when you create an array with mixed types, it will generate an NSArray instead of an Array. I wouldn't rely on this, however, since it could change in the future (AnyObject[] is automatically bridged with NSArray).

AnyObject是一种类型,您可以创建一个包含这些类型的数组(如类名所示),这意味着它可以包含任何类型的对象。NSArray不是类型绑定的,当您创建一个混合类型的数组时,它将生成一个NSArray而不是数组。不过,我不会依赖于此,因为它在未来可能会发生变化(AnyObject[]自动地与NSArray进行桥接)。

You can try this in a playground (note: dynamicType returns "(Metatype)" and I wasn't sure how to pull out the actually type so I relied on the compiler error):

你可以在一个操场上试试这个(注意:dynamicType返回“(Metatype)”,我不确定该如何提取实际类型,所以我依赖于编译器错误):

var x = [ 1, 2, "a" ]
x.dynamicType.description() // -> __NSArrayI

var y = [ 1, 2 ]
y.dynamicType.description() // -> Error: Array<Int>.Type does not have a member named 'description'.

var z: AnyObject[] = [ 1, 2, "a" ]
z.dynamicType.description() // -> Error: Array<AnyObject>.Type does not have a member named 'description'.

#4


1  

The description is correct, an Array stores multiple values of the same type. The key is that one value has multiple types. That is, for example, a String has types of String and Any; an instance of a class Ellipse : Shape has types of Ellipse, Shape, AnyObject and Any.

描述是正确的,数组存储相同类型的多个值。关键是一个值有多个类型。例如,一个字符串有各种类型的字符串;椭圆类的一个实例:形状有椭圆、形状、任何对象和任何对象的类型。

 14> class Foo {}
 15> class Bar : Foo {}
 16> var ar1 : Array<Any> = [1, "abc", Foo(), Bar()]
ar1: Any[] = size=4 {
  [0] = <read memory from 0x7fa68a4e67b0 failed (0 of 8 bytes read)>
  [1] = { ... }
  [2] = {}
  [3] = { ... }
}
 17> ar1[0]
$R5: Int = <read memory from 0x7fa68a51e3c0 failed (0 of 8 bytes read)>
 18> ar1[1]
$R6: String = { ... }
 19> ar1[2]
$R7: Foo = {}
 20> ar1[3]
$R8: Bar = {
  lldb_expr_14.Foo = {}
}
 21> ar1[0] as Int
$R9: Int = 1

#5


1  

In Swift 3 you can use :

在Swift 3中,您可以使用:

var testArray = ["a",true,3,"b"] as [Any]

#1


17  

From REPL

从REPL

 xcrun swift
  1> import Foundation
  2> var test = ["a", "b", true, "hi", 1]
test: __NSArrayI = @"5 objects" {
  [0] = "a"
  [1] = "b"
  [2] =
  [3] = "hi"
  [4] = (long)1
}
  3>

you can see test is NSArray, which is kind of AnyObject[] or NSObject[]

可以看到test是NSArray,它是AnyObject[]或NSObject[]

What happening is that Foundation provides the ability to convert number and boolean into NSNumber. Compiler will perform the conversion whenever required to make code compile.

Foundation提供了将数字和布尔值转换为NSNumber的能力。编译器将在需要时执行转换,以使代码编译。

So they now have common type of NSObject and therefore inferred as NSArray

所以他们现在有了普通的NSObject类型因此推断为NSArray


Your code doesn't compile in REPL without import Foundation.

如果没有导入基础,您的代码不会在REPL中编译。

 var test = ["a", "b", true, "hi", 1]
<REPL>:1:12: error: cannot convert the expression's type 'Array' to type 'ArrayLiteralConvertible'

 var test:Array = ["a", "b", true, "hi", 1]
<REPL>:4:18: error: cannot convert the expression's type 'Array' to type 'ExtendedGraphemeClusterLiteralConvertible'

but you can do this

但你可以这样做。

var test : Any[] = ["a", "b", true, "hi", 1]

Because they have a common type, which is Any.

因为它们有一个共同的类型,也就是任何一个。


Note: AnyObject[] won't work without import Foundation.

注意:AnyObject[]在没有导入基础的情况下无法工作。

var test:AnyObject[] = ["a", "b", true, "hi", 1]
<REPL>:2:24: error: type 'Bool' does not conform to protocol 'AnyObject'

#2


3  

To initialize an Array with arbitrary types, just use var arbitraryArray = [Any]().

要初始化具有任意类型的数组,只需使用var仲裁数组= [Any]()。

#3


2  

AnyObject is a type and you can create an array that holds those, which (as the class name implies) means it can hold any type of object. NSArrays aren't type-bound and when you create an array with mixed types, it will generate an NSArray instead of an Array. I wouldn't rely on this, however, since it could change in the future (AnyObject[] is automatically bridged with NSArray).

AnyObject是一种类型,您可以创建一个包含这些类型的数组(如类名所示),这意味着它可以包含任何类型的对象。NSArray不是类型绑定的,当您创建一个混合类型的数组时,它将生成一个NSArray而不是数组。不过,我不会依赖于此,因为它在未来可能会发生变化(AnyObject[]自动地与NSArray进行桥接)。

You can try this in a playground (note: dynamicType returns "(Metatype)" and I wasn't sure how to pull out the actually type so I relied on the compiler error):

你可以在一个操场上试试这个(注意:dynamicType返回“(Metatype)”,我不确定该如何提取实际类型,所以我依赖于编译器错误):

var x = [ 1, 2, "a" ]
x.dynamicType.description() // -> __NSArrayI

var y = [ 1, 2 ]
y.dynamicType.description() // -> Error: Array<Int>.Type does not have a member named 'description'.

var z: AnyObject[] = [ 1, 2, "a" ]
z.dynamicType.description() // -> Error: Array<AnyObject>.Type does not have a member named 'description'.

#4


1  

The description is correct, an Array stores multiple values of the same type. The key is that one value has multiple types. That is, for example, a String has types of String and Any; an instance of a class Ellipse : Shape has types of Ellipse, Shape, AnyObject and Any.

描述是正确的,数组存储相同类型的多个值。关键是一个值有多个类型。例如,一个字符串有各种类型的字符串;椭圆类的一个实例:形状有椭圆、形状、任何对象和任何对象的类型。

 14> class Foo {}
 15> class Bar : Foo {}
 16> var ar1 : Array<Any> = [1, "abc", Foo(), Bar()]
ar1: Any[] = size=4 {
  [0] = <read memory from 0x7fa68a4e67b0 failed (0 of 8 bytes read)>
  [1] = { ... }
  [2] = {}
  [3] = { ... }
}
 17> ar1[0]
$R5: Int = <read memory from 0x7fa68a51e3c0 failed (0 of 8 bytes read)>
 18> ar1[1]
$R6: String = { ... }
 19> ar1[2]
$R7: Foo = {}
 20> ar1[3]
$R8: Bar = {
  lldb_expr_14.Foo = {}
}
 21> ar1[0] as Int
$R9: Int = 1

#5


1  

In Swift 3 you can use :

在Swift 3中,您可以使用:

var testArray = ["a",true,3,"b"] as [Any]