这两个函数调用约定有什么区别?

2023-11-26

可以通过多种方式调用函数:

say(1, 2, 3) # 123
say: 1, 2, 3 # (1, 2, 3)

后者似乎通过了Positional,但除此之外我不知道它们还有什么不同。是否有任何需要了解的重要差异?您会在什么类型的情况下使用其中一种?


@jjmerelo 的回答涵盖了基础知识。这个补充性的答案旨在较为详尽,但希望不会详尽无遗,涵盖了陷阱、罕见案例和建议。

foo: valuea, valueb, ...

也许令人惊讶的是,这就是not调用子函数或方法foo.

相反,它是一个以label, foo:.

The say:您的问题中的行在普通程序中不起作用:

say: <a b c>; # Useless use of constant value a b c ...

“无用的使用”警告是指<a b c>没有以有用的方式使用。这say:不对值列表执行任何操作。它只是一个标签,没有任何作用。

想必您正在使用类似 Perl 6 REPL 的东西。 REPL 自动says 行中的最后一个值(如果未以其他方式使用),从而使该行看起来可以正常工作而不会发出警告。

.a-method:

If a 后缀方法调用使用表格.a-method除了调用者(调用者左边的参数)之外没有任何参数., or 当前主题如果没有明确的调用者)那么你可以将其写成以下形式:

42.say ;

您可以选择附加一个冒号:

42.say: ;

没有充分的理由,但它符合:

.a-method: arg2, arg3, ...

如果您想向后缀提供一个或多个参数(调用者除外).a-method打电话,那么你必须选择两种方式之一来介绍他们。

One way is to write a colon immediately after the method name, before the argument(s). There must be no space between the method name and colon, and there must be space after the colon before the method argument(s).1

例如,以下在前面使用冒号Numeric以下方法调用中的参数:

say <abc 2 def ghi> .first: Numeric ; # 2

在上面的行中,方法调用表达式 (.first: Numeric) 以语句终止符 (;)。如果存在封闭子表达式(例如数组下标),则方法调用表达式将在该子表达式的末尾结束:

say .[1 + .first: Numeric] given <abc 2 def ghi> ; # ghi

冒号形式方法调用的参数列表也由有效的语句修饰符 like given:

say .first: Numeric given <abc 2 def ghi> ; # 2

a-sub arg1, arg2, ...

这是子程序调用的相应形式。唯一的格式差异是子程序没有调用者或.在子名和您之前必须省略子名称后面的冒号。

.a-method( arg2, arg3, ... )

a-sub( arg1, arg2, ... )

用于方法和子调用的另一种常见形式是在方法或子名称后立即用括号来分隔参数。左括号必须立即遵循,例程名称和之间没有任何空格(.

这是与以下一起使用的括号.first method:

say 1 + .first(Numeric) given <abc 2 def ghi> ; # 3

这样做的优点是它可以说比使用外括号的替代方案更漂亮:

say 1 + (.first: Numeric) given <abc 2 def ghi> ; # 3

如果要将子调用直接放在双引号字符串内,则需要在子名称前添加前缀&sigil 并使用后缀括号形式:

my @array = <abc 2 def ghi> ;
say "first number is &first(Numeric,@array)" ; # first number is 2

要放入方法调用,您必须再次使用后缀括号形式,并且还必须提供显式调用者(您不能只写"Some text .a-method()"):

my @array = <abc 2 def ghi> ;
say "first number is @array.first(Numeric)" ; # first number is 2

如果没有参数(除了方法调用的调用者之外),如果您想在字符串中插入子或方法调用,您仍然需要使用带有空括号的这种形式:

my @array = <abc 2 def ghi> ;
say "no method call @array[3].uc" ;     # no method call ghi.uc
say "with method call @array[3].uc()" ; # with method call GHI
say "&rand";                            # &rand
say "&rand()";                          # 0.929123203371282

.a-method ( arrgh, arrgh, ... ) ;

这行不通。

因为.a-method后面没有冒号,则方法调用被视为完成。

这意味着下一个事物必须是表达式/语句结束者,例如;,或将对方法调用的结果进行操作的后缀运算符,或对结果和某些后续参数进行操作的中缀运算符。

But ( arrgh, arrgh, ... )这些都不是。因此,您会收到“连续两项”编译错误。

.a-method:( arrgh, arrgh, ... ) ;

.a-method: ( arrgh, arrgh, ... ) ;

一般来说,请勿混合使用:在参数周围使用括号作为方法调用的一部分。这样做没有充分的理由,因为它要么不起作用,要么只是偶然起作用,要么起作用但很可能会让读者感到困惑。

如果冒号和左括号之间没有空格,则会产生一个神秘的编译错误:

This type (QAST::WVal) does not support positional operations

留出空间似乎可行——但通常只能靠运气:

say .first: (Numeric) given <abc 2 def ghi> ; # 2

The (Numeric)是括号中的单个值,产生Numeric所以这一行与:

say .first: Numeric given <abc 2 def ghi> ; # 2

但如果括号中有两个或多个参数,事情就会出错。使用以下形式之一:

say .first: Numeric, :k given <abc 2 def ghi> ; # 1
say .first(Numeric, :k) given <abc 2 def ghi> ; # 1

这正确地产生了数组索引(“key”)2元素而不是:

say .first: (Numeric, :k) given <abc 2 def ghi> ; # Nil

这产生Nil因为.first方法对 a 没有做任何有用的事情single参数是表单的列表(Numeric, :k).

当然,你也可以偶尔want传递一个参数,该参数是括号中的值列表。但您可以不使用冒号来完成此操作。为了清楚起见,我建议您将其写为:

invocant.a-method(( valuea, valueb, ... ));

a-sub ( arrgh1, arrgh2, ... ) ;

正如刚才对方法调用所解释的,这将一个参数传递给a-sub,即单个列表( arrgh1, arrgh2, ... )这很少是作者的意思。

同样,我的建议是将其写为:

`a-sub( valuea, valueb, ... ) ;`

or:

`a-sub  valuea, valueb, ...   ;`

如果您打算传递多个参数,或者希望将列表作为单个参数传递,那么:

`a-sub(( valuea, valueb, ... )) ;`

.a-method : arrgha, arrghb, ...

a-sub : arrgha, arrghb, ...

对于方法形式,这会给你一个“混乱”的编译错误。

对于子表单来说也是如此,如果a-sub不接受任何争论。如果a-sub接受参数你会得到一个“前面的上下文需要一个术语,但发现中缀:相反”编译错误。

.&a-sub

有一种调用形式可以让您调用声明为子程序的例程——但是使用.method调用语法。以下为“调用者”提供信息qux在点的左边作为名为的子函数的第一个参数a-sub:

qux.&a-sub

Use a :或照常使用括号传递额外的论点a-sub:

sub a-sub ($a, $b) { $a == $b }
say 42.&a-sub(42), 42.&a-sub(43); # TrueFalse
say 42.&a-sub: 42;                # True

(在本节的原始版本中,我写道,一个人不能传递额外的参数。我已经对此进行了测试,并认为一个人不能。但我一定是被某些东西弄糊涂了。@Enheh 的评论让我重新测试并发现一个can就像普通方法调用一样传递附加参数。谢谢@Enheh。 :))

a-method( invocant: arg2, arg3, ... )

a-method invocant: arg2, arg3, ...

在设计文档中称为“间接对象表示法”,这些格式是一种未记录且很少见的方法调用形式,其中调用模仿方法声明 - 方法名称在前,然后是调用者,后跟冒号:

say first <abc 2 def ghi>: Numeric ; # 2

注意say is a sub调用因为下一个令牌,first, 后面没有冒号。相比之下first is a method调用,因为它后面的令牌is后面跟着一个冒号。

脚注

1 All comments about spaces/spacing in this answer ignore unspacing.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这两个函数调用约定有什么区别? 的相关文章

  • 扩展 MATLAB 函数名称的最大长度

    我编写了一个 MATLAB 程序 可以动态创建自定义 MATLAB 函数 并使用以下命令在其他 MATLAB 实例中启动它们unix命令 我使用这个程序来自动化 fMRI 神经影像分析 使用 SPM8 for MATLAB 一切正常 但是
  • R中的引用调用(使用函数修改对象)

    我刚刚接触 R 很惊讶地发现函数不会修改对象 至少看起来这是默认的 例如 我编写了一个函数 只是为了在表格中的一个标签上粘贴一个星号 它在函数内部工作 但表本身没有改变 我主要来自Ruby 那么 在 R 中使用函数更改对象的正常 可接受的方
  • 为什么这个函数要用括号括起来,后面还要加上括号? [复制]

    这个问题在这里已经有答案了 我一直在 javascript 源代码中看到这一点 但我从未真正找到使用此构造的真正原因 为什么需要这个 function stuff 为什么这样写呢 为什么不直接使用stuff本身而不是在函数中 编辑 我知道这
  • 在函数中调用其他列的控制流程

    我正在尝试在给定条件的情况下连接到函数中的其他列 本质上 我想让数据框在给定条件的情况下从长到宽 其中一列中的这些值是NA相对于同一行中具有值的另一列 转动NAs转化为特定的数字 尽管分配的值必须是特定于列的 因此 如果2010 has N
  • 创建表时 MySQL 语法错误

    我正在尝试在 Filemaker gt MySQL 转换脚本中使用此查询 表创建步骤直接从 phpMyAdmin 导出中获取 并添加到 DROP 语句中 DROP TABLE IF EXISTS artifacts CREATE TABLE
  • 在 Haskell 中,如何将嵌套上下文中的函数“应用”到上下文中的值?

    nestedApply Applicative f Applicative g gt g f a gt b gt f a gt g f b 正如类型所示 如何获得 a gt b 应用于那个a在上下文中f 感谢帮助 这是关注类型很有帮助的情况
  • 如何在运行时找到当前函数的名称?

    在使用又大又丑的 MFC ASSERT 宏多年之后 我终于决定放弃它并创建终极的 ASSERT 宏 我可以很好地获取文件和行号 甚至失败的表达式 我可以显示一个消息框 其中包含中止 重试 取消按钮 当我按下 Retry 时 VS 调试器会跳
  • 在Python中实现函数的前向声明[重复]

    这个问题在这里已经有答案了 是否可以在 python 中声明函数并单独实现它们 我的意思是在 C 中 void foo void foo C 前向声明用于解决依赖性问题 功能foo由函数使用bar and foo needs bar在声明它
  • JavaScript 函数参数和范围

    我用下面列出的代码做了一些测试 function foo x alert y var y I am defined outside foo definition foo 上面的代码给了我一个警告 我是在 foo 定义之外定义的 然后另一个测
  • 需要了解Javascript函数提升示例

    我阅读了 Javascript 提升的概念 它非常令人困惑 但我看到了一些示例并了解了提升的实际作用 所以基本上 提升是 JavaScript 的默认行为 即将所有声明移动到当前作用域的顶部 当前脚本或当前函数的顶部 但我无法理解以下实现
  • 从子函数中中断父函数(最好是 PHP)

    我面临的挑战是如何使用 PHP 中断或结束父函数的执行而不修改父函数的代码 除了 die 我想不出任何解决方案在子函数中 这将结束所有执行 因此父函数调用之后的任何内容都将结束 有任何想法吗 代码示例 function victim ech
  • 如何让 Raku 中的承诺超时?

    我知道我可以安排Promise在给定的时间内保存 my promise Promise in seconds 但我怎样才能安排它被破坏呢 具体来说 我正在考虑一个将 超时 的承诺 以便它必须保留一定的时间 否则它将失败 我可以和另一个人一起
  • 你能在 Python 语法中添加新的语句吗?

    您可以添加新的语句 例如print raise with 到 Python 的语法 说 允许 mystatement Something Or new if True print example 没那么多 如果你should 而是如果可能的
  • 大括号语法 ${var%.*} 是什么意思?

    我正在查看一些旧代码并遇到了以下语法 extractDir downloadFileName tmp 我发现搜索的唯一信息是指命令列表 但这只是一个变量 这个大括号语法在 bash 中意味着什么 在这种背景下 它是一个参数替换 http w
  • 如何重写 NQPMatch.Str 函数

    或者如何改变
  • 函数输入参数的 auto 是否可以替代函数模板?

    在 C 20 中auto关键字可用于函数输入参数 这是函数模板的适当替代吗 在决定采用哪种方法时是否需要考虑任何实际差异 template
  • 强制一个 javascript 函数等待运行,直到第一个函数完成

    下午 我遇到了一个问题 我需要运行一个函数 然后在完成后 运行下一个函数 并对四个函数执行此操作 我已经尝试了一段时间 试图找到正确的布局语法我的函数调用但似乎找不到任何东西来解决这个特定的场景 html div div div jquer
  • PHP:将字符串分成 8 个块,我该怎么做?

    我基本上有二进制 假设它的长度是300 我如何将它分割 就像使用爆炸一样 成 8 位块 我查看了 chunk split 但它似乎只有一个 end 参数 而不是将其放入数组的选项 或者它可以插入数组吗 末尾 8 位数字可以低于 8 如果有人
  • 如何禁用 Perl 6 REPL 创建 .precomp

    每次我跑步perl6进入REPL模式 它创建了一个 precomp目录 这也会减慢提示的出现速度 如果 precomp目录已经存在 提示几乎立即出现 否则perl6创建它需要几秒钟 有没有办法禁用此功能 检查您是否有PERL6LIB环境变量
  • 什么是异地退货?

    什么是非本地退货 什么场景下有用 请举个例子来解释一下 这是一篇好文章 http yehudakatz com 2010 02 07 the building blocks of ruby 关于在 ruby 块的上下文中使用非本地返回 Ru

随机推荐

  • 版本控制如何工作?

    版本控制通常如何工作 它是否将 diff 文件保存为带有哈希值的跟踪以验证跟踪 查看Eric Sinks 关于版本控制的博客系列 此外 乔尔 斯波尔斯基写道Hg Init Mercurial 教程 这最终让我 了解 了分布式源代码控制的全部
  • 将表示为链表的两个大数相加,无需反转链表

    假设您有两个用链表表示的大数字 如何将它们相加并将结果存储在单独的链表中 例如 a 2 gt 1 gt 7 b 3 gt 4 result 2 gt 5 gt 1 您可以在不颠倒链表的情况下添加它们吗 伪代码 步骤1 遍历链表并将元素压入两
  • 在 numpy.correlate 中指定滞后

    Matlab互相关函数xcorr x y maxlags 有一个选项maxlag 返回滞后范围内的互相关序列 maxlags maxlags 纳比的numpy correlate N M mode 有三种模式 但没有一种模式允许我设置特定的
  • 如何使用 Python Pillow 定义模糊半径?

    我正在尝试模糊图像Pillow using 图像过滤器如下 from PIL import ImageFilter blurred image im filter ImageFilter BLUR 这工作得很好 只是它的设定半径对我来说太小
  • 获取未旋转的旋转矩形的边界

    我有一个已经应用了旋转的矩形 我想获得未旋转的尺寸 x y 宽度 高度 这是当前元素的尺寸 Bounds at a 90 rotation height 30 width 0 x 25 y 10 以下是旋转设置为无后的尺寸 Bounds a
  • Go mgo 包中的连接池

    文章中与 go 并发运行 mongodb 查询说 mgo DialWithInfo 创建一个会话 维护与 MongoDB 的套接字连接池 但是当我在文献记录函数的拨号信息我没有找到与我谈论池连接的内容 只有我在DialFunction Di
  • ES6 地图垫片如何工作

    根据我对文档的理解 here and here 需要一个对内存地址的引用才能工作 const foo const map new Map map set foo 123 Can only be done if memory address
  • 通过通用父类访问子类中的 Java 静态成员

    这似乎是一个新问题 但上次我使用 Java 时 该语言没有泛型 我有一个类层次结构 名称更改为尽可能通用 public abstract class AbstractBase public class ConcreateSubA exten
  • 没有主目录的用户的 SSH 公钥

    我正在运行 Mac OS X Leopard Server 并且创建了一个新用户 但没有为该用户指定主目录 是否可以让该用户使用公钥进行身份验证 我知道当用户does有一个它所在的主目录 ssh authorized keys 我不想为该用
  • 在Android清单中使用largeheap是一个好的实践吗?

    我正在发展NDK 它挂在Galaxy S3 为了测试我把android largeheap true in Manifest 然后就不存在挂起的问题了 这是一个很好的做法吗largeHeap true 谷歌是否有可能因为这个标签而拒绝我的构
  • 让 Migrate.exe 正常工作

    我一直在努力执行 EF Migrate exe 来工作 我的解决方案有几个项目 迁移和实体位于项目数据中 控制器和视图位于 Web 中 我尝试使用 migrate exe 但是我很难让第一个参数 程序集 被接受 文件说 程序集 指定包含该程
  • 在后台运行exe

    我尝试过以下方法 Start Process powershell ArgumentList C Program Files Prometheus io prometheus exe WindowStyle hidden Invoke Co
  • 使用动态对象的 MongoDB C# 驱动程序序列化

    我有一个模型 看起来像 public class Record public Record Created DateTime Now public string Id get set public string ApplicationId
  • 使用 Mongoose 从 Decimal128 中提取小数 - MongoDB

    我正在使用 Mongoose 在 Nodejs 中查询 Mongo 并尝试提取存储为 Decimal128 的多个字段的数值 然而 该值奇怪地包含在查询结果中 我不确定如何通过 Mongo 或 Mongoose 提取它 data date
  • unsigned long long 与 uint64_t 冲突? [复制]

    这个问题在这里已经有答案了 我们对某些类型参数使用模板专门化 例如 class my template class
  • 与 Spring Data JPA 保持一对一关系

    我有接下来的两个实体 它们之间具有 OneToOne 关系 Entity Table name tasks public class Task OneToOne mappedBy task cascade CascadeType PERSI
  • 当内部函数返回可能为“None”的“Union”时,如何避免类型错误?

    我在Python中遇到了一些关于联合 当然还有可选 的奇怪问题 也就是说 静态类型检查器似乎针对联合的所有成员而不是联合的成员测试属性 即看起来过于严格 例如 请考虑以下情况 import pandas as pd def test dum
  • Windows 版 Caffe 中的未知图层类型(裁剪)

    我想使用以下卷积神经网络 http lmb informatik uni freiburg de people ronneber u net 与咖啡构建https github com BVLC caffe tree windows 适用于
  • 运行使用 Gradle2.0.0-alpha 插件编译的 Android(用 Kotlin 编写)项目时出错

    当用新的编译项目时gradle2 0 0 alpha我得到的插件 java lang RuntimeException Unable to instantiate application com android tools fd runti
  • 这两个函数调用约定有什么区别?

    可以通过多种方式调用函数 say 1 2 3 123 say 1 2 3 1 2 3 后者似乎通过了Positional 但除此之外我不知道它们还有什么不同 是否有任何需要了解的重要差异 您会在什么类型的情况下使用其中一种 jjmerelo