键入任何?没有下标成员
type any? has no subscript members
我想从配置文件字典中获取地址,但出现错误 "type any? has no subscript members"
var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
profile["Addresses"][0] <-----------------type any? has no subscript members
如何修复它并获取地址?非常感谢。
当您使用 "Addresses"
订阅配置文件时,您将获得一个 Any
实例。您选择使用 Any
来适应同一数组中的各种类型,这导致了类型擦除的发生。您需要将结果转换回其真实类型 [[String: Any]]
,以便它知道 Any
实例表示 Array
。然后你就可以下标了:
func f() {
let address: [[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
let profile: [String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
guard let addresses = profile["Addresses"] as? [[String: Any]] else {
// Either profile["Addresses"] is nil, or it's not a [[String: Any]]
// Handle error here
return
}
print(addresses[0])
}
虽然这很笨拙,而且首先使用字典并不是一个非常合适的情况。
在这种情况下,您的字典具有一组固定的键,结构是更合适的选择。它们是强类型的,因此您不必从 Any
进行向上和向下转换,它们具有更好的性能,并且更易于使用。试试这个:
struct Address {
let address: String
let city: String
let zip: Int
}
struct Profile {
let name: String
let age: Int
let addresses: [Address]
}
let addresses = [
Address(
address: "someLocation"
city: "ABC"
zip: 123
),
Address(
address: "someLocation"
city: "DEF"
zip: 456
),
]
let profile = Profile(name: "Mir", age: 10, addresses: addresses)
print(profile.addresses[0]) //much cleaner/easier!
您应该重新考虑您选择构建 adress
和 profile
的方式;参见例如.
对于技术讨论,您可以提取您知道包含 [String: Any]
字典的 profile
的 Any
成员Any
数组;通过顺序尝试将 profile["Addresses"]
类型转换为 [Any]
,然后逐个元素(尝试)转换为 [String: Any]
:
if let adressDictsWrapped = profile["Addresses"] as? [Any] {
let adressDicts = adressDictsWrapped.flatMap{ [=10=] as? [String: Any] }
print(adressDicts[0]) // ["Zip": 123, "City": "ABC", "Address": "someLocation"]
print(adressDicts[1]) // ["Zip": 456, "City": "DEF", "Address": "someLocation"]
}
或者,没有中间步骤...
if let adressDicts = profile["Addresses"] as? [[String: Any]] {
print(adressDicts[0]) // ["Zip": 123, "City": "ABC", "Address": "someLocation"]
print(adressDicts[1]) // ["Zip": 456, "City": "DEF", "Address": "someLocation"]
}
但这只是尝试类型化转换的一个小教训(-> 不要这样做)。
如果您按照之前的建议重新考虑您的设计,我同意。为了便于讨论,您可以执行以下操作来实现您的目标。
var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
if let allAddresses = profile["Addresses"] as? [[String:Any]] {
print("This are all the address \(allAddresses[0])")
}
我想从配置文件字典中获取地址,但出现错误 "type any? has no subscript members"
var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
profile["Addresses"][0] <-----------------type any? has no subscript members
如何修复它并获取地址?非常感谢。
当您使用 "Addresses"
订阅配置文件时,您将获得一个 Any
实例。您选择使用 Any
来适应同一数组中的各种类型,这导致了类型擦除的发生。您需要将结果转换回其真实类型 [[String: Any]]
,以便它知道 Any
实例表示 Array
。然后你就可以下标了:
func f() {
let address: [[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
let profile: [String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
guard let addresses = profile["Addresses"] as? [[String: Any]] else {
// Either profile["Addresses"] is nil, or it's not a [[String: Any]]
// Handle error here
return
}
print(addresses[0])
}
虽然这很笨拙,而且首先使用字典并不是一个非常合适的情况。
在这种情况下,您的字典具有一组固定的键,结构是更合适的选择。它们是强类型的,因此您不必从 Any
进行向上和向下转换,它们具有更好的性能,并且更易于使用。试试这个:
struct Address {
let address: String
let city: String
let zip: Int
}
struct Profile {
let name: String
let age: Int
let addresses: [Address]
}
let addresses = [
Address(
address: "someLocation"
city: "ABC"
zip: 123
),
Address(
address: "someLocation"
city: "DEF"
zip: 456
),
]
let profile = Profile(name: "Mir", age: 10, addresses: addresses)
print(profile.addresses[0]) //much cleaner/easier!
您应该重新考虑您选择构建 adress
和 profile
的方式;参见例如
对于技术讨论,您可以提取您知道包含 [String: Any]
字典的 profile
的 Any
成员Any
数组;通过顺序尝试将 profile["Addresses"]
类型转换为 [Any]
,然后逐个元素(尝试)转换为 [String: Any]
:
if let adressDictsWrapped = profile["Addresses"] as? [Any] {
let adressDicts = adressDictsWrapped.flatMap{ [=10=] as? [String: Any] }
print(adressDicts[0]) // ["Zip": 123, "City": "ABC", "Address": "someLocation"]
print(adressDicts[1]) // ["Zip": 456, "City": "DEF", "Address": "someLocation"]
}
或者,没有中间步骤...
if let adressDicts = profile["Addresses"] as? [[String: Any]] {
print(adressDicts[0]) // ["Zip": 123, "City": "ABC", "Address": "someLocation"]
print(adressDicts[1]) // ["Zip": 456, "City": "DEF", "Address": "someLocation"]
}
但这只是尝试类型化转换的一个小教训(-> 不要这样做)。
如果您按照之前的建议重新考虑您的设计,我同意。为了便于讨论,您可以执行以下操作来实现您的目标。
var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
if let allAddresses = profile["Addresses"] as? [[String:Any]] {
print("This are all the address \(allAddresses[0])")
}