2016-09-21 21 views
1

首先,我必须说我来自Java编程,并且与Java相比,Swift 3.0中的所有东西似乎都是非常复杂的。我以为我想要做的事很简单,但事实证明它并非如此。如何在没有通用的情况下使用Swift 3.0中的Set

我有两个对象:

protocol Customer { 
} 

和:

class Consulter { 
} 

我想我Consulter类来保存CustomerSet

class Consulter { 
    var customers: Set<Customer>; 
} 

确定这里的第一件事。编译器现在抱怨Customer必须实现Hashable ...真的吗?斯威夫特是不是这样对我?好。所以让我们去为它:

func ==(lhs: Customer, rhs: Customer) -> Bool { 
    return lhs.hashValue == rhs.hashValue; 
} 

protocol Customer: Hashable { 

    var: hashValue: Int { 
     return "123".hashValue; 
    } 
} 

在我Consulter类现在我必须做到以下几点:

class Consulter<T: Customer> { 

    var customers: Set<T>; 
} 

确定这是工作。但现在我有另一个类:

func ==(lhs: Location, rhs: Location) -> Bool { // here the error! 
    return lhs.hashValue == rhs.hashValue; 
} 

class Location<T: Customer> : Hashable { 

    var customer: T; 

    .... 
} 

对于类LocationEquatable我现在得到的错误:

Reference to generic type 'Location' requires arguments in <...> 

所以编译器期待什么说法吗?在这一点上,我不知道任何具体类型。

编辑

Customer协议将在以后有不同的具体实现。例如,Customer可以是FamilyPerson。在Consulter班,我想有一个SetCustomer包含:家庭和人员。我认为这是一个简单而合乎逻辑的方法。

+1

'Customer'是一种协议(可能为客户相关_types_符合),以及您希望使用的具体类型可能不是。您可以简单地包含一个约束,即符合'客户'协议意味着符合'Hashable'('协议Customer:Hashable {}')。通过这种方式,您可以将“Hashable”符合您认为是“Customer”的实际类型。 – dfri

+0

我不明白你刚刚写了什么。所以我在编辑中进一步解释我的想法。 – Mulgard

+0

由于您打算在必须是'Hashable'的应用程序中使用符合'Customer'的类型(例如,作为'Set'的成员),所以没有理由不直接将'Hashable'约束添加到'Customer '协议('协议Customer:Hashable {}')。 W.r.t.你的错误,因为'Location'是一个泛型类型,所以你必须指定泛型'T'的类型来处理一个具体类型(例如具体类型'Location ')。 – dfri

回答

1

既然你打算使用符合Customer类型的应用程序,他们必须是Hashable(例如为Set的成员),没有理由为什么不直接添加此Hashable约束到Customer协议。您将负责这种方式符合Hashable到您认为Customer

protocol Customer: Hashable {} 

class Consulter<T: Customer> { 
    var customers: Set<T>? 
} 

class Location<T: Customer>: Hashable { 
    var customer: T 
    init(customer: T) { self.customer = customer } 

    var hashValue: Int { 
     return customer.hashValue 
    } 
} 

func ==<T: Customer>(lhs: Location<T>, rhs: Location<T>) -> Bool { 
    return lhs.customer == rhs.customer /* && ... test other properties */ 
} 

而且实际的类型,使用X.hashValue == Y.hashValue用于测试平等小心,因为没有保证hashvalues是唯一的(认为它们主要用于聪明的“箱子”分类)。

或者,由于斯威夫特3

// ... as above 

class Location<T: Customer>: Hashable { 
    var customer: T 
    init(customer: T) { self.customer = customer } 

    var hashValue: Int { 
     return customer.hashValue 
    } 

    static func ==(lhs: Location<T>, rhs: Location<T>) -> Bool { 
     return lhs.customer == rhs.customer /* && ... test other properties */ 
    } 
} 
+1

这正是我需要知道的。我已经这样做了。我所需要的只是将'func ==(lhs:Location ....'移到我的课堂上,并让它变成静态的,谢谢。 – Mulgard

相关问题