swift - 如何从 Swift REPL 获取表达式的静态类型?

标签 swift

如何从 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 }

由于函数在闭包中捕获了它的参数,因此不会对参数求值,因为闭包从未被调用过。但是,这有两个缺点:

  1. 在 REPL 中调用它只会产生错误。
  2. 在脚本中调用它会返回一个 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/

相关文章:

ios - 如何在 Swift 中的 CATextLayer 上应用 GaussianBlur 滤镜

swift - 通过符合 Swift 2 中的协议(protocol)扩展类型化数组

ios - tableview 上的滚动 Action

arrays - 无法调用类型 : with an argument list of type: 的初始值设定项

ios - 当我在 block 中使用 self 时,我得到一个 nil。但是 self 没有释放

ios - 如何在特定时间在后台下载/获取数据?

ios - 如何能够响应导航项标题上的点击?

swift - 如何访问类中的对象

ios - "id"类型如何在不强制转换的情况下理解方法的接收者?

ios - 将 NSDictionary 转换为 Json String 会导致元素重新排序