考虑这段代码:
extension Collection {
func foo() -> Int {
if self.first is Collection {
return (self.first as! Collection).underestimatedCount // ERROR
}
else {
return self.underestimatedCount
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们得到了令人恐惧且明显令人困惑的情况:
协议“Collection”只能用作通用约束,因为它具有 Self 或关联的类型要求。
然而,这很高兴编译:
func foo<C: Collection>(_ c: C) -> Int where C.Iterator.Element: Collection {
if let first = c.first {
return first.underestimatedCount // *
} else {
return c.underestimatedCount
}
}
Run Code Online (Sandbox Code Playgroud)
为什么?!
特别是,编译器不知道关联*类型(的类型)first是如何实现的;它只得到了它们已经得到的承诺(因为任何类型的对象都Collection 必须实现它们)。第一个示例中也有同样的保证!那么为什么编译器会抱怨其中之一而不是另一个呢?
我的问题是:在 line 处*,编译器知道什么是它不 in …
我正在使用 Xcode 和 swift 3 为我开发一个项目。我想做的是如下。
class SCViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate{
//code here
}
Run Code Online (Sandbox Code Playgroud)
但这给了我一个错误SCViewController不符合协议NSObjectProtocol。
我想同时遵守 UIViewController 和 AVCaptureMetadataOutputObjectsDelegate。请帮助我解决这个问题。
我遇到了 Swift 协议的问题。我有这样的事情:
\n\nprotocol OnboardingPage {\n var viewModel: OnboardingPageViewModel! { get }\n}\n\nprotocol OnboardingPageViewModel {\n func getValue() -> Bool\n}\n\n// ---\n\nclass FirstNameViewController: UIViewController, OnboardingPage {\n var viewModel: FirstNameViewModel!\n}\n\nclass FirstNameViewModel: OnboardingPageViewModel {\n func getValue() -> Bool {\n return true\n }\n}\n\nclass GenderViewController: UIViewController, OnboardingPage {\n var viewModel: GenderViewModel!\n}\n\nclass GenderViewModel: OnboardingPageViewModel {\n func getValue() -> Bool {\n return false\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我有一堆确认协议的视图控制器OnboardingPage,它们都有一个符合协议的视图模型OnboardingPageViewModel协议的视图模型。
但遗憾的是上面的代码不起作用:它说不FirstNameViewController确认OnboardingPage协议,因为它的viewModel属性具有类型FirstNameViewModel而不是OnboardingPageViewModel- 即使FirstNameViewModel是OnboardingPageViewModel.
我有一个协议,并且在扩展中有它的定义。
我想对定义进行单元测试。
我用谷歌搜索但找不到任何相关内容。
我得到的最接近的是 Mocking with Protocol 或 POP 等。
如果有人可以用示例向我解释,那就太好了。
unit-testing protocols swift swift-protocols protocol-extension
let subscriber: SubscriberContextProviding我正在尝试通过简单地直接设置来更新定义为的服务的属性,WatchlistViewModel如下所示:
subscriber.watchlist = watchlist
Run Code Online (Sandbox Code Playgroud)
相关订户定义:
final class Subscriber: SubscriberContextProviding {
var watchlist = [String]()
}
Run Code Online (Sandbox Code Playgroud)
但是我收到一条错误消息:Cannot assign to property: 'subscriber' is a 'let' constant
。订阅者服务被声明为 alet并在客户端中初始化init。这是相关的协议部分 & init。
protocol SubscriberContextProviding {
var watchlist: [String] { get set }
}
class WatchlistViewModel: NSObject {
let subscriber: SubscriberContextProviding
init(subscriber: SubscriberContextProviding){
self.subscriber = subscriber
super.init()
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果我将协议从上面的协议更改为
protocol SubscriberContextProviding {
func set(watchlist: [String])
}
Run Code Online (Sandbox Code Playgroud)
我只是将函数定义subscriber为
func set(watchlist: [String]){
self.watchlist …Run Code Online (Sandbox Code Playgroud) 我有一个名为 ObjectAPIModel 的类型,它明确符合 Codable 协议。我还有一个函数,它接收一些数据并调用另一个函数将任何 JSON 解码为指定类型。但是如果我调用decodeJSON(),它会显示一个错误,指出ObjectAPIModel 不符合Decodable。有人可以帮忙吗?
struct ObjectAPIModel: Codable {
let objectID: Int
var primaryImage: String
var title: String
var department: String
}
Run Code Online (Sandbox Code Playgroud)
func decodeJSON<T: Decodable>(data: Data, ofType: T) -> Result<T, APIError> {
let decodedObject = try? JSONDecoder().decode(T.self, from: data)
if decodedObject == nil {
return .failure(APIError.emptyResponse)
} else {
return .success(decodedObject!)
}
}
Run Code Online (Sandbox Code Playgroud)
let result = decodeJSON(data: unwrappedData, ofType: ObjectAPIModel)
Run Code Online (Sandbox Code Playgroud)
我收到错误:“类型‘ObjectAPIModel.Type’不能符合‘Decodable’”
我有一个Objective C类,其方法如下所示:
@class Client;
@protocol ClientDelegate <NSObject>
@optional
-(void) receivedMessageFromClient : (id) message;
@end
@interface Client : NSObject
+(id) setup;
@property(nonatomic, strong) id <ClientDelegate> clientDelegate;
// more method declarations below
Run Code Online (Sandbox Code Playgroud)
我正在我的Swift类中实现ClientDelegate,如下所示:
class HomeViewController: UIViewController, ClientDelegate {
var client : AnyObject?
var delegate: ClientDelegate?
override func viewDidLoad() {
super.viewDidLoad()
client = Client.setup() as! Client
client.clientDelegate = self
}
func receivedMessageFromClient(message: AnyObject) {
print("Message recieved: \(message)")
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我一个编译错误:
无法分配属性:'self'是不可变的
当我删除线条
client = Client.setup() as! Client
client.clientDelegate = self
Run Code Online (Sandbox Code Playgroud)
代码编译并调用Client类中receivedMessageFromClient的方法,该方法又转发消息,但不调用该方法 …
例如:我想在协议定义中说,符合它的类还需要子类化UIView或其他自定义类 type MyClass。那可能吗?
我想知道如何在Swift中表达这种类型的关系(例如kotlin中的示例)
interface Index<K, V> {
fun getAll(key: K): Sequence<V>
}
Run Code Online (Sandbox Code Playgroud)
我试图使用具有关联类型的协议,如下所示:
protocol Index {
associatedtype Key
associatedtype Value
associatedtype Result: Sequence where Sequence.Element == Value
func getAll(key: Key) -> Result
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用(Associated type 'Element' can only be used with a concrete type or generic parameter base)
然后,作为一种解决方法,我尝试了此操作:
protocol Index {
associatedtype Key
associatedtype Value
func get<T: Sequence>(key: Key) -> T where T.Element == Value
}
Run Code Online (Sandbox Code Playgroud)
但这似乎并不是正确/惯用的方法。
只有两个约束:
笔记:
Sequence特定于每个实现的类/类型Index我愿意接受任何其他结构性改变!提前致谢。
所以我遇到了协议的主题,我在互联网上搜索了很多答案,但我找不到一个,至少一个解决了我的问题。
所以我明白协议是方法、属性等的“蓝图”,它可以在类或结构中实现,并且它需要符合其要求等,但为什么要使用一个?
我的意思是你也可以在结构本身内创建一个函数。编写协议似乎有点麻烦,然后为了实现所述协议,这次您必须使用更多代码再次编写所有要求。
人们使用协议有什么特别的原因吗?是为了您的代码安全还是出于其他原因?
例如:
在 swift 中,你有 CustomStringConvertible 协议,它有一个必需的计算属性来控制如何将自定义类型表示为可打印的 String 值,但你也可以在你的类中创建一个函数来解决这个问题。您甚至可以在不实现此协议的情况下计算出与此协议相同的属性。
因此,如果有人可以对这个主题有所了解,那就太好了。
先感谢您!
swift ×10
swift-protocols ×10
protocols ×2
casting ×1
codable ×1
decodable ×1
generics ×1
ios ×1
objective-c ×1
swift3 ×1
typechecking ×1
unit-testing ×1
xcode ×1