类型变量的范围是什么?

时间:2014-11-20 16:44:11

标签: generics swift scope type-variables

我从Swift编译器('A' is not convertible to 'A''E' is not identical to 'E')中发现了一些令人困惑的错误消息,我认为这是因为我在两个范围内引入了同名的类型变量,其中一个范围是嵌套的在另一个里面。

我希望更全面地了解类型变量的工作原理,因此我有一些相关的问题:

  • Swift中类型变量的范围是什么?
  • ow是嵌套类型和方法影响的范围?
  • 可以键入变量吗?
  • 当嵌套方法引入与封闭类同名的类型变量时会发生什么?
  • 是否可以执行类似method2(下方)的操作? (我的XCode一直在崩溃,我无法解决这个问题)

以下是一些示例,说明我想要弄清楚的内容:

class MyClass<A> {

    func method1<A>(a:A) -> A {
        // what does A refer to here?
        return a;
    }

    class func staticmethod<A>(a:A) -> A {
        // what does A refer to here?
        return a;
    }

    func method2() -> ((A) -> A) {
        // is this even possible?  
        // I'm not sure how to write method2's type !
        func id<A>(a:A) -> A {
            return a;
        }
        return id;
    }

}

1 个答案:

答案 0 :(得分:0)

泛型类/结构/方法/函数的泛型类型的范围正是如此 类/结构/方法/函数。是的,它可以被嵌套定义遮蔽。

在您的示例中,A中的method1是该方法的通用类型 调用方法时,由实际类型替换。它会影响通用 类型MyClass<A>。例如:

let mc = MyClass<Int>()      // class instantiated with actual type Int
let x = mc.method1("foo")    // method called with actual type String
println(x) // "foo"

静态方法也是如此:

let y = MyClass<Int>.staticmethod(123.5) // method called with type Double
println(y)

在你的method2中,内部函数没有得到类型参数,它应该是 (我已经删除了一对不必要的括号):

func method2a() -> (A) -> A {
    func id(a:A) -> A {
        return a;
    }
    return id;
}

func method2b<A>() -> (A) -> A {
    func id(a:A) -> A {
        return a;
    }
    return id;
}

取决于它是否适用于类的类型或引入它自己的类型 通用类型。请注意,您可以使用闭包而不是使用闭包来缩短它 嵌套函数,例如

func method2b<A>() -> (A) -> A {
    return { a in a }
}

在第一种情况下,你会像

一样使用它
let mc = MyClass<Int>()    // class instantiated with type Int, therefore 
let z = mc.method2a()(12)   // mc.method2a() has signature Int -> Int
println(z)

在第二种情况下你可以做

let mc = MyClass<Int>()   // class instantiated with type Int, but
let z = mc.method2b()("bar") // mc.method2b() has signature String -> String
println(z)

此处method2b<A>的实际类型是从参数“bar”推断为String

通常,我更喜欢为嵌套泛型类型使用不同的名称 避免不必要的混淆。