相关疑难解决方法(0)

不支持使用某些协议作为符合其他协议的具体类型

我正在尝试将泛型与协议混合在一起,我的xD非常困难

我在Android/Java项目中实现了某些架构,我正在尝试重写它以适应swift/iOS项目.但我发现了这个限制.

ProtocolA

protocol ProtocolA {

}
Run Code Online (Sandbox Code Playgroud)

ProtocolB

protocol ProtocolB : ProtocolA {

}
Run Code Online (Sandbox Code Playgroud)

ImplementProtocolA

class ImplementProtocolA <P : ProtocolA> {

    let currentProtocol : P

    init(currentProtocol : P) {
        self.currentProtocol = currentProtocol
    }

}
Run Code Online (Sandbox Code Playgroud)

ImplementProtocolB

class ImplementProtocolB : ImplementProtocolA<ProtocolB> {

}
Run Code Online (Sandbox Code Playgroud)

因此,当我尝试将ProtocolB设置为实现ProtocolA的具体类型时,我收到此错误:

不支持使用'ProtocolB'作为符合协议'ProtocolA'的具体类型

1这种"限制"有什么理由吗?

2是否有任何解决方法可以实现此功能?

3它会在某个时候得到支持吗?

- 更新 -

我认为同一问题的另一个变种是:

查看协议

protocol View {

}

protocol GetUserView : View {
    func showProgress()
    func hideProgress()
    func showError(message:String)
    func showUser(userDemo:UserDemo)
}
Run Code Online (Sandbox Code Playgroud)

演示者协议

protocol Presenter {
    typealias V : …
Run Code Online (Sandbox Code Playgroud)

protocols swift

64
推荐指数
1
解决办法
2万
查看次数

为什么协议中的get-only属性要求不能满足符合的属性?

为什么以下代码会产生错误?

protocol ProtocolA {
    var someProperty: ProtocolB { get }
}

protocol ProtocolB {}
class ConformsToB: ProtocolB {}

class SomeClass: ProtocolA { // Type 'SomeClass' does not conform to protocol 'ProtocolA'
    var someProperty: ConformsToB

    init(someProperty: ConformsToB) {
        self.someProperty = someProperty
    }
}
Run Code Online (Sandbox Code Playgroud)

这个类似问题的答案是有道理的.但是,在我的示例中,属性是get-only.为什么不能这样做?它是Swift的缺点,还是有一些合理的理由?

swift swift-protocols

35
推荐指数
1
解决办法
1138
查看次数

使用JSONEncoder以Codable作为类型对变量进行编码

我设法让JSON和plist编码和解码都工作,但只能通过直接调用特定对象上的编码/解码函数.

例如:

struct Test: Codable {
    var someString: String?
}

let testItem = Test()
testItem.someString = "abc"

let result = try JSONEncoder().encode(testItem)
Run Code Online (Sandbox Code Playgroud)

这很好,没有问题.

但是,我试图获得一个只接受Codable协议一致性类型的函数并保存该对象.

func saveObject(_ object: Encodable, at location: String) {
    // Some code

    let data = try JSONEncoder().encode(object)

    // Some more code
}
Run Code Online (Sandbox Code Playgroud)

这会导致以下错误:

无法使用类型'(Encodable)'的参数列表调用'encode'

看看编码函数的定义,似乎它应该能够接受Encodable,除非Value是一些我不知道的奇怪类型.

open func encode<Value>(_ value: Value) throws -> Data where Value : Encodable
Run Code Online (Sandbox Code Playgroud)

serialization protocols ios swift codable

35
推荐指数
1
解决办法
9158
查看次数

使用JSONEncoder对符合协议的类型进行编码/解码

我正在尝试使用Swift 4中的新JSONDecoder/Encoder找到符合swift协议的编码/解码结构数组的最佳方法.

我举了一个例子来说明问题:

首先,我们有一个协议Tag和一些符合这个协议的类型.

protocol Tag: Codable {
    var type: String { get }
    var value: String { get }
}

struct AuthorTag: Tag {
    let type = "author"
    let value: String
}

struct GenreTag: Tag {
    let type = "genre"
    let value: String
}
Run Code Online (Sandbox Code Playgroud)

然后我们有一个Type文章,它有一个标签数组.

struct Article: Codable {
    let tags: [Tag]
    let title: String
}
Run Code Online (Sandbox Code Playgroud)

最后,我们对文章进行编码或解码

let article = Article(tags: [AuthorTag(value: "Author Tag Value"), GenreTag(value:"Genre Tag Value")], title: "Article Title")


let jsonEncoder = JSONEncoder()
let jsonData = try …
Run Code Online (Sandbox Code Playgroud)

encoding json swift swift4 codable

32
推荐指数
3
解决办法
2万
查看次数

扩展可能不包含存储的属性,但为什么允许静态

扩展不能包含存储属性,但为什么可以在扩展中定义静态存储属性?

我也没有找到任何文档提到扩展中允许静态属性.

extension String {
  static let test = "Test"
  static var test2 = "Test2"
}
Run Code Online (Sandbox Code Playgroud)

swift swift-extensions

18
推荐指数
1
解决办法
5104
查看次数

泛型和协议类型函数参数之间的实际差异是什么?

给定没有任何关联类型的协议:

protocol SomeProtocol
{
    var someProperty: Int { get }
}
Run Code Online (Sandbox Code Playgroud)

这两个函数在实践中有什么区别(意思不是"一个是通用的而另一个不是")?它们是否生成不同的代码,它们具有不同的运行时特征吗?当一个或多个协议变得非常重要时,这些差异是否会发生变化?(因为编译器可能内联这样的东西)

func generic<T: SomeProtocol>(some: T) -> Int
{
    return some.someProperty
}

func nonGeneric(some: SomeProtocol) -> Int
{
    return some.someProperty
}
Run Code Online (Sandbox Code Playgroud)

我主要询问编译器的不同之处,我理解两者的语言级含义.基本上,确实nonGeneric意味着一个恒定的代码大小但速度较慢的动态调度,而不是generic每个类型传递的代码大小增加,但是使用快速静态调度?

generics swift swift-protocols

17
推荐指数
1
解决办法
1357
查看次数

为什么我不能将Protocol.Type传递给通用T.Type参数?

我正在使用Swinject,一个问题是困扰我.我差不多整整一天都被困在这里.我怀疑这是因为Swift是一种特定类型的语言,但我并不完全确定.

我在这个操场上总结了我的问题

protocol Protocol {}

class Class: Protocol {}

let test: Protocol.Type = Class.self

func printType(confromingClassType: Protocol.Type) {
    print(confromingClassType)
}

func printType<Service>(serviceType: Service.Type) {
    print(serviceType)
}

print(Class.self) // "Class"
printType(serviceType: Class.self) // "Class"
print(test) // "Class"
printType(confromingClassType: test) // "Class"

printType(serviceType: test) // "note: expected an argument list of type '(serviceType: Service.Type)'"
Run Code Online (Sandbox Code Playgroud)

我尝试了不同的解决方案,如test.self或type(of:test),但它们都不起作用.

所以我想我不能使用作为变量提供的泛型参数来调用函数?

generics protocols swift

17
推荐指数
1
解决办法
4607
查看次数

类型“任何视图”无法符合泛型协议上的“视图”

我正在使用协议来定义对默认View协议的覆盖,以在我的应用程序中创建一些模板化视图。它们都将共享CalculationComponent大部分布局的相同视图,但随后将实现使用@ViewBuilder泛型传递的不同按钮/控件。

我遇到的问题是,在定义协议主体时,通用类型在Type 'any View' cannot conform to 'View'. <Content: View>我认为这与上面的部分有直接关系CalculationComponent

计算组件.swift

struct CalculationComponent<Content: View>: View {
    @Binding var mainCalculation: String
    @Binding var secondaryCalculation: String
    @ViewBuilder var content: () -> Content
    
    var body: some View {
        // Template UI here

        content()
    }
}

Run Code Online (Sandbox Code Playgroud)

CalculationView.swift

protocol CalculationView: View {
    var mainCalculation: String { get set }
    var secondaryCalculation: String { get set}
    var body: CalculationComponent<View> { get } // Type 'any View' …
Run Code Online (Sandbox Code Playgroud)

generics xcode ios swift swiftui

17
推荐指数
1
解决办法
3万
查看次数

无法在Swift中的另一个协议中使用协议作为关联类型

我有一个协议,Address它继承自另一个协议Validator,并Address满足Validator扩展中的要求.

还有另一个协议,FromRepresentable它有一个associatedType(ValueWrapper)要求Validator.

现在,如果我尝试使用Addressas associatedType,那么它不会编译.它说,

推断类型'Address'(通过匹配要求'valueForDetail')无效:不符合'Validator'.

这种用法是非法的吗?我们是不是应该能够使用Address的地方Validator,因为所有Addresses都是Validator.

下面是我正在尝试的一段代码.

enum ValidationResult {
    case Success
    case Failure(String)
}

protocol Validator {
    func validate() -> ValidationResult
}

//Address inherits Validator
protocol Address: Validator {
    var addressLine1: String {get set}
    var city: String {get set}
    var country: String {get set}
}

////Fulfill Validator protocol requirements in extension
extension …
Run Code Online (Sandbox Code Playgroud)

ios associated-types swift swift-protocols

12
推荐指数
1
解决办法
3259
查看次数

KV在Swift 4中保留一个协议

我正在努力在Swift 4中使用新的强类型KVO语法来观察仅通过协议可见的属性:

import Cocoa

@objc protocol Observable: class {
    var bar: Int { get }
}

@objc class Foo: NSObject, Observable {
    @objc dynamic var bar = 42
}

let implementation = Foo()

let observable: Observable = implementation

let observation = observable.observe(\.bar, options: .new) { _, change in
    guard let newValue = change.newValue else { return }

    print(newValue)
}

implementation.bar = 50
Run Code Online (Sandbox Code Playgroud)
error: value of type 'Observable' has no member 'observe'
let observation = observable.observe(\.bar, options: .new) { _, change …
Run Code Online (Sandbox Code Playgroud)

key-value-observing swift-protocols swift4

11
推荐指数
1
解决办法
893
查看次数