在R语言中能否自定义原语?或类原语的操作符与语法?
这个问题问到点子上了!很多R用户都会好奇能不能扩展语言本身的核心语法,咱们来好好唠唠:
核心结论:无法完全自定义R的原生原语,但能实现外观/功能高度接近的语法结构
首先得明确:R里的$、[、for()这些所谓的“原语”(Primitive),是底层用C写死在R解释器里的核心语法元素——它们的解析规则、执行逻辑都是语言本身的一部分,普通用户没办法直接新增一个完全等价的自定义原语(比如直接用拢作为无分隔符的语法,像list_of_lists拢a这种写法,R的解释器根本认不出来)。
不过别灰心,咱们有很多替代方案,完全能满足你的需求:
1. 中缀运算符(你已经在用的%拢%)
这是最直接也最推荐的方式,R允许自定义%xxx%格式的中缀运算符,语法简洁,体验和原生运算符几乎一致:
`%拢%` <- function(list_of_lists, element_name) { lapply(list_of_lists, `[[`, element_name) } # 测试用例 list_of_lists <- list(list(a=1, b=2), list(a=3, b=4)) list_of_lists %拢% "a" # 输出:[[1]] 1 [[2]] 3
如果觉得加引号麻烦,还可以改一下让它支持直接传符号:
`%拢%` <- function(list_of_lists, element_name) { elem <- deparse(substitute(element_name)) lapply(list_of_lists, `[[`, elem) } list_of_lists %拢% a # 同样能得到正确结果,不用加引号
2. 模拟“前缀式”简洁语法
虽然不能直接写list_of_lists拢a,但可以把拢做成函数,用接近的调用方式:
拢 <- function(x, elem) { elem_name <- deparse(substitute(elem)) lapply(x, `[[`, elem_name) } # 调用时只需要加一对括号,视觉上很接近你想要的效果 拢(list_of_lists, a) # 输出:[[1]] 1 [[2]] 3
3. 给原生运算符加自定义方法(针对特定对象)
如果你的嵌套列表有专属的类,还可以给$、[这些原生运算符添加自定义方法,让它们直接实现你要的“拢”功能:
# 给嵌套列表打个自定义类标签 list_of_lists <- list(list(a=1, b=2), list(a=3, b=4)) class(list_of_lists) <- "nested_list" # 重写$运算符的行为 `$.nested_list` <- function(x, name) { lapply(x, `[[`, name) } # 现在直接用原生$语法就能实现你的需求! list_of_lists$a # 输出:[[1]] 1 [[2]] 3
这种方式对熟悉R的用户来说特别友好,完全复用原生语法,学习成本几乎为零。
总的来说,虽然没法直接新增一个R原生级别的原语,但通过上面这些方法,完全能实现功能、体验都和原生原语高度类似的自定义操作,甚至还能根据你的需求做更灵活的扩展。
内容的提问来源于stack exchange,提问作者Ma Ba
相关产品推荐
相关产品推荐

