从Swift REPL,如何获取表达式的静态类型?
例如,在Haskell中,我可以:type
用来获取表达式的类型:
Prelude> :type "hello"
"hello" :: [Char]
Prelude> :type (1 + 1)
(1 + 1) :: Num a => a
这表示“ hello”的类型是的列表Char
,而(1 + 1)的类型a
是type class中的某种类型Num
。
Swift REPL上没有明显的方法可以执行此操作,但我认为使用该语言已提供的功能可能是可行的。到目前为止,这是我已经弄清楚的。如果有人持有这个难题的缺失,我将很高兴。
这些是各种选择,没有一个是正确的:
顾名思义,dynamicType返回实例的动态确定类型,而不是计算实例的表达式的静态类型。另外,对于REPL类型,它似乎不适用于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
此函数(由可能希望保持匿名的贡献者建议)返回一个字符串,其名称为foo类型。但是,它计算表达式foo。而且,它并不总是返回静态类型,正如运行下面的脚本所看到的那样,其中,解拆功能将给出随机计算的动态类型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)")
听起来最接近的是Twitter上@jckarter的建议,以定义以下功能:
func staticType<T>(@autoclosure () -> T) -> T.Type { return T.self }
由于函数在闭包中捕获其自变量,因此不会评估自变量,因为从不调用闭包。但是,这有两个缺点:
如果我们知道如何获取ObjC和Swift类型的MetaType的名称,这足以使最后一种方法起作用,至少在脚本中(如果不是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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句