Swift中的命名空间

·  阅读 83

导言:

总所周知C++中是有命名空间的说法,比如我们将使用的using namespace std;我们就可以直接使用std空间下的cout,而不必每次都这样std::cout加一个std::。

Swift中是没有像C++那样显示的命名空间说法的。但是强大的Swift语言支持是可以帮我们完成的。那么为什么需要命名空间呢?有时候我们使用别人的第三方库或者我们写库来供他人使用的时候,就可能出现变量、方法等出现重名的情况。那么如果有命名空间的存在的话,就可以达到各司其职的作用。比如第三方库和你的项目中对UIView进行了扩展,可直接通过某个view.width获取宽度,但是我们项目中也进行了扩展,可能会出现编译不通过的情况。那么我们下面用命名空间来解决。

1.首先创建我们的包装类,可以看到这里是一个范型

  // 包装类
  struct YH<Base> {
      var base: Base
      init(_ base: Base) {
          self.base = base
      }
  }

2.创建一个协议用于达到命名空间的作用

  // YHSizeCompatible协议用来实现命名空间
  protocol YHSizeCompatible {}
  // 由于协议的声明不能有默认的实现,所以我们可以声明一个空的协议,然后通过extension来达到有默认实现的效果。
  extension YHSizeCompatible {
      static var yh: YH<Self>.Type { return YH<Self>.self }
      var yh: YH<Self> { return YH(self) }
  }

3.比如这里我们希望使用我们自己的扩展来获取某个UIView对象的width和height,我们对UIView进行扩展让其实现我们的YHSizeCompatible协议。那么该UIView就具有我们的YH类型的yh的静态变量和yh的实例变量。然后对我们的YH结构体进行扩展并使用where语句对范型Base进行类型的约束。

  extension UIView: YHSizeCompatible {}
  extension YH where Base: UIView {
      var width: CGFloat {
          return base.frame.width
      }
      var height: CGFloat {
          return base.frame.height
      }
  }

4.至此我们就可以使用我们命名空间下的width和height了。下面看具体的使用例子:

          let testView = UIView(frame: .init(x: 0, y: 0, width: 100, height: 200))
          print("width = (testView.yh.width),height = (testView.yh.height)")
  //width = 100.0,height = 200.0


在举一个例子:在比如我们可以自定义自己的随机颜色

  extension UIColor: YHCompatible {}
  extension YH where Base: UIColor {
      static func RGBRandomColor() -> UIColor {
          return UIColor(red: CGFloat(arc4random_uniform(256))/255.0, green: CGFloat(arc4random_uniform(256))/255.0, blue: CGFloat(arc4random_uniform(256))/255.0, alpha: 1.0)
      }
  }

我们看如何使用:

  
  let randomColor1 = UIColor.yh.RGBRandomColor()
  let randomColor2 = UIColor.yh.RGBRandomColor()
  print(randomColor1)
  print(randomColor2)

最近开始学习RXSwift了,看到rx中也有这样的命名空间,可见命名空间中对于swift框架和库的开发过程中的重要地位。

public struct Reactive<Base> {

    /// Base object to extend.

    public let base: Base

    /// Creates extensions with base object.

    ///

    /// - parameter base: Base object.

    public init(_ base: Base) {

        self.base = base

    }

}

/// A type that has reactive extensions.

public protocol ReactiveCompatible {

    /// Extended type

    associatedtype CompatibleType

    /// Reactive extensions.

    static var rx: Reactive<CompatibleType>.Type { get set }

    /// Reactive extensions.

    var rx: Reactive<CompatibleType> { get set }

}

extension ReactiveCompatible {

    /// Reactive extensions.

    public static var rx: Reactive<Self>.Type {

        get {

            return Reactive<Self>.self

        }

        set {

            // this enables using Reactive to "mutate" base type

        }

    }
    
    /// Reactive extensions.

    public var rx: Reactive<Self> {

        get {

            return Reactive(self)

        }

        set {

            // this enables using Reactive to "mutate" base object

        }

    }

}

import class Foundation.NSObject

/// Extend NSObject with `rx` proxy.

extension NSObject: ReactiveCompatible { }

\

分类:
iOS
标签:
分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改