Perl6 中的类型强制
Posted
技术标签:
【中文标题】Perl6 中的类型强制【英文标题】:Type coercion in Perl6 【发布时间】:2018-11-26 17:50:12 【问题描述】:如果我有一个 Str 类型的对象,并且我想将其强制转换为 Int,我的理解是可以通过调用 Str 对象上的方法 Int 来做到这一点,如下所示:
"100".Int
我(想我)知道我可以做到这一点,因为https://docs.perl6.org/type/Str 的 Str 类型文档列出了 Int 方法。现在,为了将这个新创建的 Int 强制转换为 Complex 类型的对象,我尝试了以下强制:
"100".Int.Complex
哪个有效 :-) 所以没问题。除了我无法弄清楚它为什么起作用。 https://docs.perl6.org/type/Int 的 Int 类型文档没有列出方法 Complex。我确实为 ComplexStr 类找到了一个具有此名称的方法,但我不知道这是否与我的 Int 相关。
所以问题是:上述强制是如何工作的? Complex 方法从何而来?在尝试之前我怎么知道我实际上可以在 Int 对象上调用它?
【问题讨论】:
【参考方案1】:(这更像是一个扩展评论而不是一个答案。我只知道 Perl 5。)
来自https://docs.perl6.org/type/Cool:
Cool 中的方法将调用者强制转换为更具体的类型,然后 在该类型上调用相同的方法。例如 Int 和 Str 从 Cool 继承,并在 Int 上调用方法 substr 转换 整数到 Str 首先。
123.substr(1, 1); # '2', same as 123.Str.substr(1, 1)
所以看起来123.substr(1, 1)
就像Cool(123).substr(1, 1)
采用更传统的表示法,然后重写为Str(123).substr(1, 1)
,因为Str
继承自Cool
(就像反向完成的经典OOP)。
以类似的方式,"100".Int.Complex
似乎就像Cool("100").Int.Complex -> Int("100").Complex -> 100.Complex -> Cool(100).Complex -> Complex(100)
。
【讨论】:
在 REPL 中,123.WHAT
返回 (Int)
,并且 Int 类型的文档清楚地表明,可以在 Int 上调用例程 substr,因为该例程是从 Cool 继承/提供的。因此,您提到的示例似乎已被文档以简单的方式涵盖。 "100".WHAT
,但是返回 (Str)
,而 "100".Int
返回 (Int)
,正如 Str 类型文档所预测的那样。但是 Int 类型的文档没有列出方法 Complex; Cool-type 文档也没有。所以我迷失在 100.Complex 阶段。
嗨 @Ozzy - 我喜欢查看 perl6 文档中的类型图 - 这是来自 ComplexStr 的一个 - 但您可能想从另一点开始 docs.perl6.org/type/ComplexStr#Type_Graph【参考方案2】:
这只是文档不完整的情况。
您总是可以通过在对象上调用.^methods
来了解对象支持哪些方法:
perl6 -e '$_>>.name.join(", ").say for 123.^methods.sort(*.name).rotor(5 => 0, :partial)'
ACCEPTS, Bool, Bridge, Capture, Complex
DUMP, FatRat, Int, Num, Numeric
Range, Rat, Real, Str, WHICH
abs, acos, acosec, acosech, acosh
acotan, acotanh, asec, asech, asin
asinh, atan, atan2, atanh, base
ceiling, chr, cis, conj, cos
cosec, cosech, cosh, cotan, cotanh
exp, expmod, floor, gist, is-prime
isNaN, log, log10, lsb, msb
narrow, new, perl, polymod, pred
rand, roots, round, sec, sech
sign, sin, sinh, sqrt, succ
同时,我pushed a commit to the docs repo 添加了缺失的方法。该网站已通过更改重新生成:https://docs.perl6.org/type/Int#(Real)_method_Complex
【讨论】:
命令应该是 perl6 -e '$_>>.name.join(", ").say for 123.^methods.sort(*.name).rotor(5 , :partial )' 否则你会错过最后四种方法 tan, tanh, truncate, unpolar以上是关于Perl6 中的类型强制的主要内容,如果未能解决你的问题,请参考以下文章