【问题标题】:Most efficient way of dealing with multiple functions that have the same signature but different parameters处理具有相同签名但不同参数的多个函数的最有效方法
【发布时间】:2020-04-19 10:35:25
【问题描述】:

目前我有多个具有相同签名但在调用 base 时执行不同操作的函数:

func drawPath(from: JMapDestination, to: JMapDestination) {
    guard let fromWaypoint = navigationManager.getWaypointForDestination(destination: from),
        let toWaypoint = navigationManager.getWaypointForDestination(destination: to) else {
            return
    }

    drawPath(from: fromWaypoint, to: toWaypoint)
}


func drawPathFrom(_ from: CGPoint, to: JMapDestination) {
    guard let fromWaypoint = getWaypointForPoint(point: from),
        let toWaypoint = navigationManager.getWaypointForDestination(destination: to) else {
            return
    }

    drawPath(from: fromWaypoint, to: toWaypoint)
}



func drawPath(from: CGPoint, to: JMapWaypoint) {
    guard let fromWaypoint = getWaypointForPoint(point: from) else { return }
    drawPath(from: fromWaypoint, to: to)
}

我决定使用 switch 语句创建一个枚举和一个主函数来处理不同的情况:

enum pathType {
    case jMapWaypoint
    case jMapDestination
    case cgPoint
}


func drawPath(pathType: pathType, fromJMap: JMapWaypoint?, toJMap: JMapWaypoint?, fromJDestination: JMapDestination?, toJDestination: JMapDestination?, fromCGPoint: CGPoint?) {

    switch pathType {

    case .jMapWaypoint:
        guard let mapController = viewModel?.mapController else {
            return
        }

        let pathStyle = setPathStyle(style: JMapStyle.init())
        if let from = fromJMap, let to = toJMap {
            checkPathsBetweenWaypoints(mapController: mapController, pathStyle: pathStyle, from: from, to: to)
        }
        if let currentMap = mapController.currentMap {
            mapController.zoomToPath(on: currentMap, withPadding: 100, withAnimationDuration: 1)
        }

    case .jMapDestination:
        if let from = fromJDestination, let to = toJDestination {
            guard let fromWaypoint = getWaypointForDestination(destination: from),
                let toWaypoint = getWaypointForDestination(destination: to) else {
                    return
            }
            drawPath(pathType: .jMapWaypoint, fromJMap: fromWaypoint, toJMap: toWaypoint, fromJDestination: nil, toJDestination: nil, fromCGPoint: nil)
        }

    case .cgPoint:
        if let from = fromCGPoint, let to = toJMap {
            guard let fromWaypoint = getWaypointForPoint(point: from) else { return }
            drawPath(pathType: .jMapWaypoint, fromJMap: fromWaypoint, toJMap: to, fromJDestination: nil, toJDestination: nil, fromCGPoint: nil)
        }
    }
}

带有 switch 语句的函数正在工作,但我想知道是否有更清洁、更有效的方法来执行此操作?仅供参考,所有功能都在同一个 viewController 上,我在考虑协议,但如果协议函数签名相同(即 drawPath)但参数不同,如何做到这一点?

【问题讨论】:

  • 你有一个方法也接受 JMapWaypoint 作为 from 和 to 参数吗?
  • @Harsh 我有,因为功能很大,所以我没有在帖子中包含它
  • 这里没有什么低效的地方,但这是一种糟糕的编码风格。根据类型向自己发送秘密消息是一个非常糟糕的主意。说出你的意思,是我的建议。

标签: ios swift switch-statement overloading


【解决方案1】:

更简洁的版本(恕我直言)将是一个包含路径开始和结束的结构,例如:

struct MyPath {

    var start: JMapWaypoint
    var end: JMapWaypoint

    init(start: CGPoint, end: CGPoint)
    {
        //Your logic here
    }
    init(start: JMapWaypoint, end: JMapWaypoint)
    {
        self.start = start
        self.end = end
    }
    init(start: JMapDestination, end: JMapDestination)
    {
        //Your logic here
    }
} 

然后你可以简单地用你想要的任何类型初始化这个对象,得到最终想要的类型并用这个对象实例绘制你的路径。

【讨论】:

    【解决方案2】:

    我不知道这是否是正确的方法...为方便起见,我会为CGPointJMapDestination 创建扩展名,这将有一种将其转换为JMapWaypoint 的方法称为func asWaypoint。最后我会使用扩展方法来调用最终方法,而不是跳过这么多圈。

    例子:

    extension CGPoint {
       func asWaypoint() -> JMapWaypoint {
          // your logic for the conversion 
       }
    }
    

    然后将最终方法称为 drawPath(from: from.asWaypoint(), to: to.asWaypoint())

    希望这会有所帮助。

    【讨论】:

    • 这个方法很有意思,我试试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多