Generic/Polymorphic 在 Swift 中搜索

Generic/Polymorphic search in Swift

好的,所以我正努力在 Swift 中成为泛型、多态性和面向协议编程的专家。我正在慢慢地将所有这些拼凑在一起,最后在我正在制作的应用程序的网络框架中散布了一些通用功能。我的问题是,我这样做对吗?

假设我有一个用户 class:

public class User {
  public var familyName: String?
  public var givenName: String?
  public internal(set) var userID: String?
  public var color: UIColor? 
}

我还有一个 UserController 可以帮助我跟踪为用户分配随机颜色、跟踪各种网络调用中的用户以及排序和过滤。这是我拥有的一个功能,可以让我通过 属性 目前可用的内容搜索用户:

public func getUser<T>(compareValue E: T) -> UEUser? {
    let potentialUsers = self.users.filter({ (user) -> Bool in
        if user.userID == E as? String {
            return true
        }else if user.familyName == E as? String{
            return true
        }else if user.givenName == E as? String{
            return true
        }else if user.color == E as? UIColor{
            return true
        }else{
            return false
        }
    })
    return potentialUsers.first
}

其中 self.users 是由控制器管理的用户数组。

这个函数使用泛型来避免我为每个 属性.

编写搜索函数

我想知道是否有更多的多态方式来比较函数参数和用户属性?另外,从 class 设计的角度来看,我可以利用面向协议的编程来用更少的代码完成通用搜索吗?

谢谢

首先让我说,我知道您正在进行学术探索练习以理解泛型,但在这种特殊情况下,确实没有必要使用泛型来编写您展示的函数。同样的解决方案可以写成:

func getUser(compareValue: Any) -> User? {
    return all_users.first(where: { (user: User) -> Bool in
        return user.userID == compareValue as? String ||
            user.familyName == compareValue as? String ||
            user.givenName == compareValue as? String ||
            user.color == compareValue as? UIColor
    })
}

我只是使用 Any 类型作为搜索参数的替代。

如果您坚持使用多态解决方案来比较 属性 值,也许这种技术会吸引您的学术追求:

func compare_property<T>(_ property : T?, _ value : Any) -> Bool where T:Comparable {
    return property == value as? T
}

func compare_property<T>(_ property : T?, _ value : Any) -> Bool where T:NSObject {
    if let prop = property {
        return prop.isEqual(value as? T)
    } else {
        return value == nil
    }
}

var all_users : [User] = []
func getUser(compareValue: Any) -> User? {
    return all_users.first)(where: { (user: User) -> Bool in
        return compare_property(user.userID, compareValue)  ||
        compare_property(user.familyName,compareValue) ||
        compare_property(user.givenName, compareValue) ||
        compare_property(user.color, compareValue)
    })
}

就使用更少的代码而言...我的解决方案通过利用以下事实使用更少的代码行:比较是可以使用基本操作组合的 Bool 值。不用说(本质上):

if myExpression {
  return true
} else {
  return false
}

此 "if" 表达式的计算结果与 "myExpression" 相同,因此在其周围放置 "if" 语法有点过分。