我正在尝试在Swift中扩展类NSDictionary以包含在init()上设置的NSDate.当我添加自定义init()时,我得到编译器错误:
'required'初始化程序'init(dictionaryLiteral :)'必须由'NSDictionary'的子类提供
但是,当我使用自动完成添加初始化程序时,我收到以下错误:
来自扩展的声明无法覆盖
有没有办法覆盖NSDictionary的初始化程序或者Swift只是不能处理它?
这是我的班级:
class DateParam : NSDictionary {
let date : NSDate
init(date: NSDate) {
super.init()
self.date = date
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
required convenience init(dictionaryLiteral elements: (NSCopying, AnyObject)...) {
fatalError("init(dictionaryLiteral:) has not been implemented")
}
}
Run Code Online (Sandbox Code Playgroud) 在Swift中,扩展是一种在事后定义类成员的方法.或者,你可以说,它是(来自一个全新的)组合函数的奇特方式:
extension Double {
var mm: Double { return self * 1_000.0 }
func mm1() -> Double { return self * 1_000.0 }
}
func mm(a: Double) -> Double {
return a * 1_000.0
}
print("One meter is \(1.mm) milimeters")
print("One meter is \(1.mm1()) milimeters")
print("One meter is \(mm(1)) milimeters")
Run Code Online (Sandbox Code Playgroud)
我从来没有见过这样的东西.在任何其他语言中都有这样的东西吗?
我习惯使用扩展在协议内部使用默认参数,因为协议声明本身不能使用它们,如下所示:
protocol Controller {
func fetch(forPredicate predicate: NSPredicate?)
}
extension Controller {
func fetch(forPredicate predicate: NSPredicate? = nil) {
return fetch(forPredicate: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
为我工作完美.
现在我有下一个情况,我有一个特定类型的控制器的特定协议:
protocol SomeSpecificDatabaseControllerProtocol {
//...
func count(forPredicate predicate: NSPredicate?) -> Int
}
Run Code Online (Sandbox Code Playgroud)
和协议扩展以及控制器的默认方法的实现:
protocol DatabaseControllerProtocol {
associatedtype Entity: NSManagedObject
func defaultFetchRequest() -> NSFetchRequest<Entity>
var context: NSManagedObjectContext { get }
}
extension DatabaseControllerProtocol {
func save() {
...
}
func get() -> [Entity] {
...
}
func count(forPredicate predicate: NSPredicate?) -> Int {
...
}
//..... …Run Code Online (Sandbox Code Playgroud) 我有一个返回JSON对象数组的API.我已将结构设置为如下所示:
typealias MyModels = [MyModel]
struct MyModel: Codable {
let field1: String
let field2: String
let mySubModel: SubModel?
enum CodingKeys: String, CodingKey {
case field1 = "Field1"
case field2 = "Field2"
case mySubModel = "MySubModel"
}
}
struct SubModel: Codable {
let subModelField1: String
let subModelField2: String
enum CodingKeys: String, CodingKey {
case subModelField1 = "SubModelField1"
case subModelField2 = "SubModelField2"
}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是添加此扩展,提供路径var(NetworkModel协议为API操作提供了一些基本功能):
extension MyModels: NetworkModel {
static var path = "the/endpoint/path"
}
Run Code Online (Sandbox Code Playgroud)
当base是对象或json键时,我在这种方式设置的其他模型/结构类中没有任何问题.但是,由于这个是不同的,并且只是一个数组,当我在该类中放入该扩展时,我收到此错误:
Constrained extension must be declared on …Run Code Online (Sandbox Code Playgroud) 我想为我的结构创建一个 init 方法,其中包含一堆用于单元测试的默认值。我不希望主模块能够看到这个 init 方法。
我以为我可以简单地在我的测试类文件中创建结构的扩展,但这不起作用:
Foo.swift(在应用程序目标中):
public struct Foo {
public let bar: Int
public init(colour: String) {
self.bar = colour == "Green" ? 0 : 1
}
}
Run Code Online (Sandbox Code Playgroud)
FooExtension.swift(在测试目标中):
extension Foo {
public init(bar: Int = 42) {
self.bar = bar
}
}
Run Code Online (Sandbox Code Playgroud)
请注意主文件中的非默认初始化程序,因此 Swift 编译器不会自动为我创建成员初始化程序。也许这与问题有关,也许不是。
Swift 编译器抱怨Cannot assign to 'bar' in 'self'。但是当我将该 init 方法复制到Foo我的主要目标中结构的原始定义中时,它工作正常。无论是否使用默认参数值,我都会得到相同的结果。
这是一个 Swift 编译器错误还是与在一个模块中为另一个定义的结构定义扩展有关?当我尝试在 Playground 中复制它时,一切正常。
我使用 Swift 1.2 和 Xcode 版本 6.4 (6E35b)
根据Swift官方文档(Swift扩展文档),Swift扩展看起来像Java枚举.
Swift extensions:
extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// prints "One inch is 0.0254 meters"
Run Code Online (Sandbox Code Playgroud)
我试图在Java中表示这个并提出以下代码.这个Java表示是否正确?还是有其他方式代表这个?
public enum LengthMetric {
km(1.0e3), mm(1.0e-3), m(1.0e0);
private final double number; …Run Code Online (Sandbox Code Playgroud) 我想扩展一个类型化数组Array<SomeType>,使其符合协议SomeProtocol。现在我知道您可以扩展如下的类型化数组:
extension Array where Element: SomeType { ... }
Run Code Online (Sandbox Code Playgroud)
您还可以扩展对象以遵循以下协议:
extension Array: SomeProtocol { ... }
Run Code Online (Sandbox Code Playgroud)
但是我无法弄清楚什么是使类型化数组符合协议的正确语法,例如:
extension (Array where Element: SomeType): SomeProtocol { ... }
Run Code Online (Sandbox Code Playgroud)
任何Swift 2专家都知道该怎么做?
我正在尝试为我的FieldIdentifiable协议创建扩展,只有实现它的枚举具有Int的RawValue.唯一的问题是该return FieldIdItem(rawValue: newValue)行一直显示此错误:
'Self.FieldIdItem' cannot be constructed because it has no accessible initializers
Run Code Online (Sandbox Code Playgroud)
这是一个Swift bug还是我错过了什么?
enum SignUpField: Int, FieldIdentifiable {
case Email = 0, Password, Username
typealias FieldIdItem = SignUpField
}
protocol FieldIdentifiable {
typealias FieldIdItem
func next() -> FieldIdItem?
func previous() -> FieldIdItem?
}
extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int {
func next() -> FieldIdItem? {
let newValue: Int = self.rawValue+1
return FieldIdItem(rawValue: newValue)
}
func previous() -> FieldIdItem? {
return FieldIdItem(rawValue: self.rawValue-1)
}
}
Run Code Online (Sandbox Code Playgroud) 我想创建一个函数来获取Dictionary并返回所述字典,但将其值作为键,将其键作为其各自的值。到目前为止,我已经做了一个函数来做到这一点,但我无法将它变成extensionfor Dictionary。
func swapKeyValues<T, U>(of dict: [T : U]) -> [U : T] {
let arrKeys = Array(dict.keys)
let arrValues = Array(dict.values)
var newDict = [U : T]()
for (i,n) in arrValues.enumerated() {
newDict[n] = arrKeys[i]
}
return newDict
}
Run Code Online (Sandbox Code Playgroud)
let dict = [1 : "a", 2 : "b", 3 : "c", 4 : "d", 5 : "e"]
let newDict = swapKeyValues(of: dict)
print(newDict) //["b": 2, "e": …Run Code Online (Sandbox Code Playgroud) 我正在阅读一个教程,我注意到作者扩展了他们的称为 Activity 的协议,并在他们的代码中编写了函数的主体。这确实可以编译,但我的印象是协议仅显示方法签名,或者如果它确实实现了主体,那么它将是一个变异函数。下面的代码没有对其函数之一使用变异,但它仍然可以运行并且可以工作!有人可以解释这种现象或确认协议扩展可以有方法体吗?
import CareKit
import SwiftyJSON
enum ActivityType: String {
case Intervention
case Assessment
}
enum ScheduleType: String {
case Weekly
case Daily
}
enum StepFormat : String {
case Scale
case Quantity
}
protocol Activity {
var identifier : String { get set}
var groupIdentifier : String { get set}
var title : String { get set}
var colour : UIColor? { get set}
var text : String { get set}
var startDate : Date { get set} …Run Code Online (Sandbox Code Playgroud) swift ×10
swift-extensions ×10
generics ×2
collections ×1
dictionary ×1
enums ×1
function ×1
ios ×1
java ×1
methods ×1
nsdictionary ×1
swap ×1
swift2 ×1
type-alias ×1