假设我们有以下示例代码:
protocol MyProtocol {
func someFunction()
}
public class MyClass {
}
public extension MyClass: MyProtocol {
func someFunction() {
print("hello")
}
}
Run Code Online (Sandbox Code Playgroud)
编译上面的代码会出现以下错误:
错误:'public'修饰符不能与声明协议一致性的扩展一起使用
如果我将扩展名标记为,则会出现同样的情况private.它好像不能设置符合协议的扩展的访问级别,无论使用什么访问级别设置为中.甚至将协议声明设置为public或private不删除错误.
如果Swift符合协议,Swift以这种方式限制扩展访问级别的原因是什么?如果在类级别应用协议一致性,则不存在此类限制.
如果我服从编译器并删除private/ public指定,那么访问级别是someFunction()多少?
extension MyClass: MyProtocol {
func someFunction() {
print("hello")
}
}
Run Code Online (Sandbox Code Playgroud)
我想在这种情况下,它将遵循原始的MyClass实现,public但我不确定.
这种行为是否存在,因为扩展中的协议一致性意味着整个类符合协议,因此在扩展中重新指定访问级别是多余的?
我想在Swift中为(例如)两个值的元组编写扩展.例如,我想写这个swap方法:
let t = (1, "one")
let s = t.swap
Run Code Online (Sandbox Code Playgroud)
这s将是(String, Int)有价值的类型("one", 1).(我知道我可以很容易地实现一个swap(t)函数,但这不是我感兴趣的.)
我可以这样做吗?我似乎无法在extension声明中写出正确的类型名称.
另外,我想答案是一样的,我可以让2元组采用给定的协议吗?
Set是一系列独特元素的无序集合.几乎与数组类似.
我想在一个Set中添加/插入多个元素String.但是只提供了一种方法,只能插入一个元素(接受单个Set元素作为参数参数),我收集了字符串(id).
@discardableResult mutating func insert(_ newMember: Set.Element) -> (inserted: Bool, memberAfterInsert: Set.Element)
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
我尝试过:
我尝试创建一个非常类似于insert(_:)方法的扩展,但它可以接受多个Set元素.它与使用迭代而不是集合相同,但不需要在任何地方手动处理它.
extension Set {
@discardableResult mutating func insert(_ newMembers: [Set.Element]) -> (inserted: Bool, memberAfterInsert: Set.Element) {
newMembers.forEach { (member) in
self.insert(member)
}
}
}
Run Code Online (Sandbox Code Playgroud)
它应该工作,如果我按预期返回一个元组但不知道如何以及在哪里(哪一行)以及返回值的内容.
这是错误消息.
期望返回的函数中缺少返回'(inserted:Bool,memberAfterInsert:Set.Element)'
什么可以解决这个问题.是否有更好的解决方案/方法来处理此操作?
let numberSet = Set(1...11)
let divideSet = numberSet.map({ $0 / 10 })
//Error: Set does not have a member named map :(
Run Code Online (Sandbox Code Playgroud)
Swift 1.2支持Set()无序集合,但map(_:)似乎不适用于集合,所以我决定在我的操场上变聪明并尝试:
let stringSet = Set(map(numberSet, { String($0)}))
println(stringSet)
stringSet = ["2", "11", "1", "8", "6", "4", "3", "9", "7", "10", "5]
Run Code Online (Sandbox Code Playgroud)
这似乎有效.所以我尝试扩展Set:
extension Set {
func map<U>(transform: (T) -> U) -> Set<U> {
return Set(Swift.map(self, transform)) }
}
Error: "couldn't find initialiser for Set(T) that accepts argument of type U"
Run Code Online (Sandbox Code Playgroud)
我认为它有一个很好的理由,它不起作用,就像这个例子:
let smarDividSet …Run Code Online (Sandbox Code Playgroud) 作为测试,我创建了两个框架.两个框架都包含此扩展:
public extension UIDevice {
var extraInfo: UIDeviceExtraInfo {
return UIDeviceExtraInfo()
}
}
public class UIDeviceExtraInfo {
public var prop: String = "Device1" //"Device2" is used in another framework
}
Run Code Online (Sandbox Code Playgroud)
然后我导入了两个框架并尝试打印UIDevice.currentDevice().extraInfo.prop.Swift编译器给出错误:Ambiguous use of extraInfo".
如何解决这样的名字冲突?
我尝试为UIView编写一个静态方法,它从nib实例化该类的视图.方法应该是通用的,并且适用于每个UIView子类.另外,我想保存类型信息 - 例如,在此代码中
let myView = MyView.loadFromNib()
Run Code Online (Sandbox Code Playgroud)
编译器推断出myView有MyView类.经过几次试验,我决定使用协议扩展,否则我将无法访问Self内部方法体.
看起来这应该工作:
protocol NibLoadable {
static func loadFromNib(name: String?) -> Self
}
extension NibLoadable where Self: UIView {
static func loadFromNib(name: String? = nil) -> Self {
let nibName = name ?? "\(self)"
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiateWithOwner(nil, options: nil)[0] as! Self
}
}
extension UIView: NibLoadable {}
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.我收到编译错误
Method 'loadFromNib' in non-final class 'UIView' must return `Self` to conform to …Run Code Online (Sandbox Code Playgroud) 坦率地说,我是学习扩展创建和使用的新手.
我想创建一个类别(在swift 3.0中扩展),可以在整个应用程序中使用它来执行Array的重复操作.
这是我在研究时所看到和理解的,我想创建一个扩展,其中包含各种方法,这些方法应该是通用的,而不是基于创建单独扩展所需的数据类型.
在上面的示例中,如果我们将使用特定的数据类型明智扩展,我们将需要创建单个扩展.如果有任何方法可以创建泛型类别(在swift中扩展),我想要一个指导.
extension _ArrayType where Generator.Element == Intextension Array where Element: Equatableextension Array where Element == Intextension _ArrayType where Generator.Element == Floatextension SequenceType where Self.Generator.Element: FloatingPointTypeextension Array where Element: DoubleValueextension Sequence where Iterator.Element == String,等等...
注意:简而言之,我们可以考虑在单个扩展中执行基于Array的操作,而不是按照上述要求为每个数据类型创建单个扩展.
我有这个功能:
func flatten<Key: Hashable, Value>(dict: Dictionary<Key, Optional<Value>>) -> Dictionary<Key, Value> {
var result = [Key: Value]()
for (key, value) in dict {
guard let value = value else { continue }
result[key] = value
}
return result
}
Run Code Online (Sandbox Code Playgroud)
如您所见,它将[Key: Value?]字典转换为[Key: Value]一个字典(没有可选字段).
我想Dictionary用一个新方法扩展该类只适用于值为Optional任何类型的类,但我无法为字典的泛型参数添加约束.
这是我试过的:
extension Dictionary where Value: Optional<Any> {
func flatten() -> [Key: Any] {
var result = [Key: Any]()
for (key, value) in self {
guard let value = value else …Run Code Online (Sandbox Code Playgroud) 我正在将下面的Objective C类重写为Swift:
@implementation UIImage (Extra)
+ (UIImage *)validImageNamed:(NSString *)name
{
UIImage *image = [self imageNamed:name];
NSAssert(image, @"Unable to find image named '%@'", name);
return image;
}
Run Code Online (Sandbox Code Playgroud)
这要求作为一个方便的init实现,但是如何检查指定的初始化程序self.init(命名:)是否成功?
extension UIImage {
convenience init(validateAndLoad name: String!) {
self.init(named: name)
// need to assert here if self.init fails
}
Run Code Online (Sandbox Code Playgroud)
当self.init(named :)调用失败时,扩展的init停止执行.
我已经尝试创建一个UIImage实例并将其分配给自己,但这不会编译.
当然,可以像ObjC版本一样使用辅助方法:
extension UIImage {
class func validImage(named name: String) -> UIImage {
var image = UIImage(named: name)
assert(image == nil, "Image doesn't exist")
return image
}
Run Code Online (Sandbox Code Playgroud)
但有没有办法使用初始化程序实现这一点?
我正在尝试使用条件扩展创建MKMapViewDelegate的默认实现,如下所示:
extension MKMapViewDelegate where Self: NSObject {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
...
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
...
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我编译代码时,我得到了警告
非'@ objc'方法'mapView(_:viewFor :)'不满足'@objc'协议'MKMapViewDelegate'的可选要求
我期望NSObject对'Self'的一致性意味着警告不会发生.除了警告之外,即使委托实例是UIViewController并且因此符合NSObject,也不会调用委托方法.
我是否误解了"哪里"在扩展中的作用?
swift ×10
swift-extensions ×10
ios ×3
protocols ×2
tuples ×2
dictionary ×1
generics ×1
namespaces ×1
set ×1
swift2 ×1