我试图弄清楚如何定义一个采用以下两个参数的函数:
例如,给定
protocol P { }
class C : P { } // Class, conforming to P
class D { } // Class, not conforming to P
struct E: P { } // Struct, conforming to P
Run Code Online (Sandbox Code Playgroud)
这应该编译:
register(P.self, obj: C()) // (1)
Run Code Online (Sandbox Code Playgroud)
但这些不应该编译:
register(P.self, obj: D()) // (2) D does not conform to P
register(P.self, obj: E()) // (3) E is not a class
Run Code Online (Sandbox Code Playgroud)
如果我们放弃第二个参数是类实例的条件,这很容易:
func register<T>(proto: T.Type, obj: T) {
// ... …Run Code Online (Sandbox Code Playgroud) 我有快速的代码:
protocol ParentProtocol {
// stuff
}
protocol ChildProtocol: ParentProtocol {
// additional stuff
}
protocol FooProtocol {
var variable: ParentProtocol? { get }
}
class Foo:FooProtocol {
var variable: ChildProtocol?
}
Run Code Online (Sandbox Code Playgroud)
我有编译器错误:
类型'Foo'不符合协议'FooProtocol'
我知道,根据FooProtocol,变量类型必须是ParentProtocol类型.另一方面ChildProtocol继承自ParentProtocol,所以它也是一个ParentProtocol
是否有任何解决方案以这种方式使用协议继承?
我在Swift中遇到泛型问题(3):
我从服务器获得不同类的不同数据,实现相同的协议,我需要将它们放入具有泛型的类(例如Array)中.
我不知道数据属于哪个类,所以我需要使用协议.所以我有以下结构:
我的协议:
protocol MyProtocol {
// some protocol stuff
}
Run Code Online (Sandbox Code Playgroud)
一些实现协议的类
class MyProtocolImpl1: MyProtocol{
// some class stuff
}
class MyProtocolImpl2: MyProtocol {
// some class stuff
}
....
Run Code Online (Sandbox Code Playgroud)
通用类:
final class MyGenericsClass<T: MyProtocol> {
// some class stuff
}
Run Code Online (Sandbox Code Playgroud)
现在我想以这种方式使用这个类:
func createClass<T>(model: T.Type) -> MyGenericClass<T> {
let myClass = MyGenericClass<T>()
return myClass
}
...
Run Code Online (Sandbox Code Playgroud)
编辑
func getClass() -> MyProtocol.Type {
return MyProtocolImpl1.self
}
let impl1 = getClass()
let impl2 = MyProtocolImpl2.self
let createdClass = createClass(impl1) //not working …Run Code Online (Sandbox Code Playgroud) 我想有一种通用的方式来做类似Swift 3:
public protocol Callable {
associatedtype In : CVarArg
associatedtype Out : CVarArg
}
public struct IntCallable : Callable {
public typealias In = Int
public typealias Out = Double
public typealias FunctionalBlock = @convention(c) (In) -> Out
public func call(_ block: FunctionalBlock) { /* do stuff */ }
}
Run Code Online (Sandbox Code Playgroud)
所以我希望它看起来像这样:
public protocol Callable {
associatedtype In : CVarArg
associatedtype Out : CVarArg
typealias FunctionalBlock = @convention(c) (In) -> Out
}
public struct IntCallable : Callable {
public typealias …Run Code Online (Sandbox Code Playgroud) 我有一个通用结构声明如下:
struct WeakReference<T: AnyObject> {
weak var value: T?
init(value: T?) {
self.value = value
}
}
Run Code Online (Sandbox Code Playgroud)
和一个协议:
protocol SomeProtocol: class {
}
Run Code Online (Sandbox Code Playgroud)
但我无法声明 类型的变量WeakReference<SomeProtocol>,编译器抱怨说
“WeakReference”要求是
SomeProtocol类类型
有趣的是,在 Swift 中,class是 AnyObject 的类型别名。
我实际上想保存一个数组,WeakReference<SomeProtocol>因为该数组保存强引用。
Swift 中的仅类泛型约束是一个类似的问题,但并没有真正解决这个问题。
我们如何传递SomeProtocolto WeakReference?
编辑: 以下场景编译良好,但我们失去了保存弱引用的能力:
struct Reference<T> {
var value: T?
init(value: T?) {
self.value = value
}
}
var array: [Reference<SomeProtocol>] = []
Run Code Online (Sandbox Code Playgroud) 使用Swift 3.0(我可以使用Swift 4.0,如果这对我有帮助......但我认为不会)我想要Erase两级.我要键入什么来擦除具有相关类型的协议,该协议符合协议本身又具有相关类型的协议.所以可以说我想键入擦除嵌套关联类型.
下面的代码是我的代码的极其简化的版本,但它更清楚.所以我真正想要的是这样的:
protocol Motor {
var power: Int { get }
}
protocol Vehicle {
associatedType Engine: Motor
var engine: Engine { get }
}
protocol Transportation {
associatedType Transport: Vehicle
var transport: Transport { get }
}
Run Code Online (Sandbox Code Playgroud)
然后我想输入erase Transportation并能够存储一个阵列,AnyTransportation其中任何Vehicle一个可以拥有任何东西Motor.
所以这是一个包含3个协议的场景,其中2个具有(嵌套)关联类型.
我不知道该怎么做.实际上,我甚至不知道如何解决更简单的场景:
我们可以将上面的原始场景简化为我们有2个协议的版本,其中只有1个协议具有关联类型:
protocol Vehicle {
var speed: Int { get }
}
protocol Transportation {
associatedtype Transport: Vehicle
var transport: …Run Code Online (Sandbox Code Playgroud) 鉴于这个类:
class MyClass: Codable {
var variable : Codable? = nil
}
Run Code Online (Sandbox Code Playgroud)
我得到错误:
类型“MyClass”不符合协议“Decodable”
类型“MyClass”不符合协议“Encodable”
如何将符合 Codable 的通用变量作为 Codable 类中的属性?
以一个非常接近在下面看一下:
// Note that this protocol can only be applied to reference types.
protocol Ref: class {
var zibbles: Int { get set }
}
class Reference: Ref {
var zibbles: Int = 42
}
// Note very carefully that we are NOT passing an
// instance, but a type itself.
func thwip<T: AnyObject>(into target: T.Type) {
}
// This compiles.
thwip(into: Reference.self)
// This fails to compile.
thwip(into: Ref.self)
Run Code Online (Sandbox Code Playgroud)
无论情况多么罕见,这是语言应该能够完成的事情.编译器知道Ref必须符合的任何实例AnyObject,因此类型约束thwip应该可以工作,但事实并非如此.
请注意,如果我们 …
我正在尝试编写一个通用函数来解析几种不同的数据类型。
最初这个方法只适用于 Codable 类型,所以它的泛型类型被约束,<T: Codable>一切都很好。不过现在,我正在尝试扩展它以检查返回类型是否为 Codable,并根据该检查相应地解析数据
func parse<T>(from data: Data) throws -> T? {
switch T.self {
case is Codable:
// convince the compiler that T is Codable
return try? JSONDecoder().decode(T.self, from: data)
case is [String: Any].Type:
return try JSONSerialization.jsonObject(with: data, options: []) as? T
default:
return nil
}
}
Run Code Online (Sandbox Code Playgroud)
所以,你可以看到类型检查工作正常,但我被困在得到JSONDecoder().decode(:)接受T的Codable类型,一旦我检查了,这是。上面的代码不能编译,有错误
Cannot convert value of type 'T' (generic parameter of instance method 'parse(from:)') to expected argument type 'T' (generic parameter …
我试图找出是否有关于 Swift 协议associatedtype使用 a=而不是:.
例如。
associatedtype Thing = SomeOtherThing
与
associatedtype Thing: SomeOtherThing
不要与我typealias Thing = SomeOtherThing始终=相信的(可能让我困惑的)混淆。
我试图抽象包含委托并使用=for associatedtypes 的类的用法,直到遇到一个问题,即该类型的变量由于 而没有公开其属性=,而是需要通常的:,这对我来说是从某种意义上说,但是当我将一个特定更改=为 a时:,它导致一切都崩溃了。我在下面提供了一个示例,其中的想法是能够自由获取/设置委托对象,但或多或少有一个协议说它的委托必须是关联类型的类型(带有 )而=不仅仅是正如似乎暗示的那样,“你必须遵守这一点” :。
我也不知道我是否迈出了这一步太过分的一步,还有其他更好的方法可以在测试方面表达这一点。这似乎是必需的,因为我不能完全依赖外部对象在测试中按预期工作,而是需要模拟它以故意失败,在某些情况下如此。
import Foundation
// Concrete objects (eg external framework)
protocol ManagerDelegate: AnyObject {
func managerDidSomething(_ manager: Manager)
}
class Manager {
weak var delegate: ManagerDelegate?
func doSomething() {
delegate?.managerDidSomething(self)
}
}
// …Run Code Online (Sandbox Code Playgroud)