是否可以在没有%%的情况下定义运算符?

Kun*_*Ren 10 r operator-keyword

在R中允许用户定义的运算符,但似乎只% %接受类似运算符.是否有可能绕过这个限制来定义运算符,例如>>,或者不喜欢的东西% %

操作员必须是真正的操作员,以便我们可以像1 >> 2使用它一样使用它">>"(1,2).

Kon*_*lph 17

不,R只允许你

  1. 重新定义现有运营商(例如`+`或确实`<-`),
  2. 通过围绕它们来定义新的中缀运算符%…%.

这些是我们必须遵守的规则.但是,在这些规则中,一切都是公平的和游戏.例如,我们可以重新定义`+`字符串以执行连接,而不会破坏其正常含义(添加):

`+`
# function (e1, e2)  .Primitive("+")
Run Code Online (Sandbox Code Playgroud)

这是旧的定义,我们希望为数字保留:

`+.default` = .Primitive('+')
`+.character` = paste0`1
`+` = function (e1, e2) UseMethod('+')
1 + 2
# [1] 3
'hello' + 'world'
# [1] "helloworld"
Run Code Online (Sandbox Code Playgroud)

这利用了R中的S3类系统`+`,使其第一个参数的类型具有通用性.

因此可以重新定义的运算符列表非常折衷.首先,它包含以下运算符:

+,-,*,/,^,&,|,:,::,:::,$,=, <-,<<-,==,<,<=,>,>=,!=,~,&&,||, !,?,@,:=,(,{,[

(取自模块源代码.)

此外,您可以[[通过重新定义来覆盖`:=`.这似乎很少有意义 - 但至少有一个很好的例子,定义较少冗长的lambda:

a = 1
(a) = 2
# Error in (a) = 2 : could not find function "(<-"
{a} = 3
# Error in { : could not find function "{<-"
Run Code Online (Sandbox Code Playgroud)

实施作为要点

  • 实际上所有 `*&lt;-` 变体都可以免费使用(`+&lt;-` 等)。控制流结构也可以被认为是一种运算符,如果由于某种原因语法对替代操作有意义,它们可以被重新定义,尽管我还没有找到一个用例,尽管我尝试了比我应该做的更多:)。今天我第一次发现如何通过使用 `-&gt;` 劫持运算符优先级来使 `while&lt;-` 工作:`'while&lt;-' &lt;- function(x,y, value) {print(x); 打印(y);打印(值);x*y*value};X &lt;- 1; Y &lt;- 2; Z &lt;- 3; Z -&gt; while(X){Y}; X` (2认同)

Ric*_*ven 5

您可以执行此类操作,但为了安全起见,您可能希望将这些对象分配给新环境。

> "^" <- function(x, y) `-`(x, y)  ## subtract y from x
> 5 ^ 3
# [1] 2

> "?" <- function(x, y) sum(x, y)  ## add x and y
> 5 ? 5
# [1] 10
Run Code Online (Sandbox Code Playgroud)

  • 这些只是因为您正在重新分配一个现有的运算符(即`^` 用于使用幂运算而`?` 通常用于帮助)。如果您尝试使用不同的符号集,例如 `&lt;&lt;`,解析器将无法理解并抛出错误。如果其他函数依赖于它们的标准定义,重新分配可能不是一个好主意。 (5认同)