Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何创建约束到结构的泛型类?_Swift - Fatal编程技术网

Swift 如何创建约束到结构的泛型类?

Swift 如何创建约束到结构的泛型类?,swift,Swift,正如前面所指出的,泛型类型可以是类或协议的约束,如下所示: public class MyGenericClass<T:Equatable> { func printEquality(a:T, b:T) { if a == b { print("equal") } else { print("not equal") } } } 你不能(从Swift 2.2开始) 这根本不

正如前面所指出的,泛型类型可以是类或协议的约束,如下所示:

public class MyGenericClass<T:Equatable> {
    func printEquality(a:T, b:T) {
        if a == b {
            print("equal")
        } else {
            print("not equal")
        }
    }
}
你不能(从Swift 2.2开始)

这根本不可能。没有
AnyObject
struct
版本,即
AnyValue
协议(自动为所有值类型实现)


我自己也面临过这个问题,很抱歉,除了严格遵守非正式协议之外,没有别的解决办法。希望Swift 3能解决这个问题。

另一个答案很好地回答了这个问题(即:你不能(还?)

但是,我想我应该补充一点,您至少可以使用运行时自省和可失败的初始化器来模拟这种行为;这样,只有当
T
是一个结构(符合
equalable
)时,泛型类的初始化才会成功

公共类MyGenericClass{
var foo:T
初始?(条形图:T){
foo=bar
如果镜像(反射:foo).displayStyle!=.Struct{
归零
}
}
}
结构Foo:equalable{
设foo=1
}
func==(lhs:Foo,rhs:Foo)->Bool{return lhs.Foo==rhs.Foo}
/*范例*/
如果let=MyGenericClass(条:1){
打印(“整数”)
}
如果let=MyGenericClass(bar:Foo()){
打印(“Foo结构”)
}
//仅打印“Foo结构”

您可以将初始化失败解释为您的泛型
T
不符合“只允许
T
成为结构”,并可能在实践中使用可选绑定(/…)将其用于观察者类。

在Swift中,Int实际上是struct,Double实际上是struct等。您可以检查与任何对象的一致性(不一致)如果bar是AnyObject{//bar是引用类型,class}否则{//bar是值类型,struct}不要混合类型和显示样式!!!@user3441734我将OP:s的问题解释为关于在显式结构类型的意义上约束协议“成为结构”(不是本质上隐藏在后台的本机类型,结构)。对于
.displayStyle
,反思本机值类型将返回
nil
,因此在上面的示例中只允许“纯结构”。如果OP要求“仅将泛型约束到值类型”(但特别是不提及结构),那么,
AnyObject
解决方案是一个不错的选择。不过,在我解释这个问题时,这要求涵盖所有值类型(包括本机值类型)。@dfri感谢您的解决方案。我也在考虑类似的问题。@Klaas很乐意提供帮助。继承只与类(引用类型)相关.SomeInheritedProtocol在Swift中没有意义。与协议相关的是一致性。但是,运行时检查某些类型的实例是否符合任何对象协议,请使用is运算符或密切相关::@user3441734代码段是“协议”中的引用是的,你是对的。他们谈论协议继承…我的错。
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
    // class-only protocol definition goes here
}
public class MyGenericClass<T: Equatable> {
    var foo: T

    init?(bar: T) {
        foo = bar

        if Mirror(reflecting: foo).displayStyle != .Struct {
            return nil
        }
    }
}

struct Foo : Equatable {
    let foo = 1
}
func ==(lhs: Foo, rhs: Foo) -> Bool { return lhs.foo == rhs.foo }

/* Example */
if let _ = MyGenericClass<Int>(bar: 1) {
    print("Integer")
}
if let _ = MyGenericClass<Foo>(bar: Foo()) {
    print("Foo-Struct")
}
// prints only "Foo-Struct"