如何从 Swift REPL 获取表达式的静态类型?
例如,在 Haskell 中,我可以使用 :type
来获取表达式的类型:
Prelude> :type "hello"
"hello" :: [Char]
Prelude> :type (1 + 1)
(1 + 1) :: Num a => a
这表明“hello”的类型是Char
的列表,而(1 + 1)的类型是类型类中的某个类型a
编号
。
在 Swift REPL 上没有明显的方法可以做到这一点,但我认为使用该语言已经提供的设施可能是可行的。这是我到目前为止所知道的。如果有人能找到缺失的那 block 拼图,我会很高兴。
这些是各种选择,没有一个是完全正确的:
1。动态类型
顾名思义,dynamicType 返回实例的动态确定类型,而不是计算实例的表达式的静态类型。此外,它似乎不适用于 Swift 类型的 REPL:
1> 1.dynamicType
error: could not fetch result -- Couldn't apply expression side effects : Couldn't dematerialize result: corresponding symbol wasn't found
2> struct Foo { let val:Int = 1 }
3> let f = Foo()
4> f.dynamicType
error: could not fetch result -- Couldn't apply expression side effects : Couldn't dematerialize result: corresponding symbol wasn't found
2。 _stdlib_getDemangledTypeName(foo)
此函数(由可能希望保持匿名的贡献者建议?)返回一个名称为 foo 类型的字符串。但是,它计算表达式 foo。此外,它并不总是返回静态类型,正如通过运行下面的脚本可以看到的那样,其中 de-mangling 函数将给出随机计算的动态类型 A 或 B 之一的名称,而不是静态可确定的类型 Any:
#!/usr/bin/swift
import Foundation
class Letter { } ; class A : Letter {} ; class B : Letter {}
func randomAny() -> Any { println("side-effecting!"); return (arc4random() % 2) == 0 ? A() : B() }
let x : Any = randomAny() // x has the static type of Any
let typeNameOfX = _stdlib_getDemangledTypeName(x)
println("the constant x with static type Any reports a type name of : \(typeNameOfX)")
3。自定义泛型函数
听起来最接近的是 Twitter 上@jckarter 的建议,即定义以下函数:
func staticType<T>(@autoclosure () -> T) -> T.Type { return T.self }
由于函数在闭包中捕获了它的参数,因此不会对参数求值,因为闭包从未被调用过。但是,这有两个缺点:
- 在 REPL 中调用它只会产生错误。
- 在脚本中调用它会返回一个 MetaType 实例,似乎没有通用的方法可以从 MetaType 实例转换为人类可读的字符串,指示该实例描述的类型。
如果我们知道如何获取元类型的名称,对于 ObjC 和 Swift 类型,这就足以使最后一种方法起作用,如果不是 REPL,至少在脚本中是这样。
最佳答案
Swift REPL 自动打印表达式的类型和结果。
1> 1 + 1
$R0: Int = 2
所以也许可以使用:
1> ({ 1 + 1 })
$R0: (() -> Int) = ($__lldb_expr8`__lldb_expr_1.(closure #1) at repl.swift:1)
^^^
或
1> reflect({ 1 + 1 }).valueType
$R0: Any.Type = () -> Int
^^^
2> ({ 1 + 1 }).dynamicType as Any.Type
$R1: Any.Type = () -> Int
最后,稍微调整一下 3。自定义通用函数:
1> func typeof<T>(@autoclosure () -> T) -> Any.Type { return T.self }
2> typeof(1 + 1)
$R0: Any.Type = Swift.Int
关于swift - 如何从 Swift REPL 获取表达式的静态类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27044331/