为什么这个Swift代码没有编译?
protocol P { }
struct S: P { }
let arr:[P] = [ S() ]
extension Array where Element : P {
func test<T>() -> [T] {
return []
}
}
let result : [S] = arr.test()
Run Code Online (Sandbox Code Playgroud)
编译器说:"类型P不符合协议P"(或者,在Swift的更高版本中,"不支持使用'P'作为符合协议'P'的具体类型.").
为什么不?不知怎的,这感觉就像语言中的漏洞.我意识到问题源于将数组声明arr为协议类型的数组,但这是不合理的事情吗?我认为协议正是为了帮助提供类似层次结构的结构?
我正在尝试从API端点返回的数据呈现视图。我的JSON看起来(大致)如下:
{
"sections": [
{
"title": "Featured",
"section_layout_type": "featured_panels",
"section_items": [
{
"item_type": "foo",
"id": 3,
"title": "Bisbee1",
"audio_url": "http://example.com/foo1.mp3",
"feature_image_url" : "http://example.com/feature1.jpg"
},
{
"item_type": "bar",
"id": 4,
"title": "Mortar8",
"video_url": "http://example.com/video.mp4",
"director" : "John Smith",
"feature_image_url" : "http://example.com/feature2.jpg"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我有一个对象,表示如何在我的UI中布局视图。看起来像这样:
public struct ViewLayoutSection : Codable {
var title: String = ""
var sectionLayoutType: String
var sectionItems: [ViewLayoutSectionItemable] = []
}
Run Code Online (Sandbox Code Playgroud)
ViewLayoutSectionItemable 是一种协议,其中包括要在布局中使用的图像的标题和URL。
但是,sectionItems数组实际上由不同的类型组成。我想做的是将每个小节实例化为自己类的实例。
如何设置的init(from decoder: Decoder)方法,ViewLayoutSection以便让我遍历该JSON数组中的项目并在每种情况下创建适当的类的实例?
我正在使用Swift 4和Codable一点点,并且遇到了一些具有嵌套协议的场景,这些协议都符合Codable.
简化示例如下所示:
protocol CodableSomething: Codable {}
protocol CodableAnotherThing: Codable {
var something: CodableSomething { get }
}
struct Model: CodableAnotherThing {
var something: CodableSomething
}
Run Code Online (Sandbox Code Playgroud)
此代码使用Xcode 9 Beta 5进行构建错误:
现在,我没想到这些错误,因为我理解编译器会自动生成对这些协议的一致性,实际上,我甚至无法在没有构建错误的情况下手动实现此一致性.我也尝试了几种不同的方法来解决这种嵌套模型结构的使用,Codable但我无法使其工作.
我的问题:这是一个编译器错误(它仍然是测试版)或者我做错了什么?
我有一个带有一组值的JSON:
[
{ "tag": "Foo", … },
{ "tag": "Bar", … },
{ "tag": "Baz", … },
]
Run Code Online (Sandbox Code Playgroud)
我想将这个数组解码为一个structs 数组,其中特定类型取决于标记:
protocol SomeCommonType {}
struct Foo: Decodable, SomeCommonType { … }
struct Bar: Decodable, SomeCommonType { … }
struct Baz: Decodable, SomeCommonType { … }
let values = try JSONDecoder().decode([SomeCommonType].self, from: …)
Run Code Online (Sandbox Code Playgroud)
我怎么做?目前我有这个有点丑陋的包装:
struct DecodingWrapper: Decodable {
let value: SomeCommonType
public init(from decoder: Decoder) throws {
let c = try decoder.singleValueContainer()
if let decoded = try? c.decode(Foo.self) {
value …Run Code Online (Sandbox Code Playgroud)