Erlang中的冒号和哈希运算符

Erlang中的冒号和哈希运算符,erlang,operators,Erlang,Operators,Erlang文档提供了一个示例 表中的前两个运算符,:和#似乎没有在文档中的其他任何地方描述。从技术上讲,#看起来像地图更新表达式中的二进制运算符,但这并不十分清楚。我没有看到关于:操作员的描述,但可能遗漏了什么 是否有人对:和#运算符有有用的技术说明?(我开始在中查找,但冒号的出现次数超过700次,这使得搜索非常困难。)对我来说,它只返回14次,远远少于700次:) :~/otp/lib/stdlib/src%cat erl_parse.yrl|grep“:” “(''”,''->“{'}”[

Erlang文档提供了一个示例

表中的前两个运算符,
#
似乎没有在文档中的其他任何地方描述。从技术上讲,
#
看起来像地图更新表达式中的二进制运算符,但这并不十分清楚。我没有看到关于
操作员的描述,但可能遗漏了什么


是否有人对
#
运算符有有用的技术说明?(我开始在中查找,但冒号的出现次数超过700次,这使得搜索非常困难。)

对我来说,它只返回14次,远远少于700次:)

:~/otp/lib/stdlib/src%cat erl_parse.yrl|grep“:”

“(''”,''->“{'}”[''”,“{''''.''”,“{''.'''.'''.'''.''”[''”,''-''对我来说,它只返回14次,远远少于700次:)

:~/otp/lib/stdlib/src%cat erl_parse.yrl|grep“:”

“(''),''->''{''}''['']''他们都不是合适的运算符。这里的文件有误导性。#字符用于base-N-literals,如在16#ffff中,但这是在词汇级别,在记录和映射的语法中,但不是作为实际运算符。:字符在远程调用中使用,就像在lists:reverse(Xs)中一样,但它实际上不是一个运算符-“lists:reverse”本身不是一个带值的子表达式。

它们都不是正确的运算符。这里的文件有误导性。#字符用于base-N-literals,如在16#ffff中,但这是在词汇级别,在记录和映射的语法中,但不是作为实际运算符。:字符在远程调用中使用,就像在lists:reverse(Xs)中一样,但它也不是一个真正的运算符-“lists:reverse”本身不是一个带值的子表达式。

从技术上讲,它们是运算符。它们不需要是有价值的表达式,也可以看到定义:也可以是C++中成员访问运算符的一个例子(类似于Erlang中的‘:’:我同意在整数文本中使用<代码>α<代码>是微语法的一部分,简单地是令牌中的字符,当然不是操作符。对于映射更新,它看起来确实像一个操作符,尽管大家一致认为对于映射文本,它似乎是语法的一部分。关于结肠的观点很好;它绝对是一个用于访问模块中元素的运算符。要将某个对象称为运算符,应该可以用语法将其描述为应用于本身具有意义的部分,并且您应该能够根据部分的意义赋予整个对象一个定义明确的意义。#很接近,但仅在词汇层面上定义;e、 g.“16#X”或“B#10”没有任何意义。然而,“M:F”在语言中本身没有意义;只有“M:F(…)”是这样。同样,对于地图更新,您不能将#与{…}部分分开。从技术上讲,它们是运算符。它们不需要是有价值的表达式,也可以看到定义:也可以是C++中成员访问运算符的一个例子(类似于Erlang中的‘:’:我同意在整数文本中使用<代码>α<代码>是微语法的一部分,简单地是令牌中的字符,当然不是操作符。对于映射更新,它看起来确实像一个操作符,尽管大家一致认为对于映射文本,它似乎是语法的一部分。关于结肠的观点很好;它绝对是一个用于访问模块中元素的运算符。要将某个对象称为运算符,应该可以用语法将其描述为应用于本身具有意义的部分,并且您应该能够根据部分的意义赋予整个对象一个定义明确的意义。#很接近,但仅在词汇层面上定义;e、 g.“16#X”或“B#10”没有任何意义。然而,“M:F”在语言中本身没有意义;只有“M:F(…)”是这样。类似地,对于地图更新,您不能将#与{…}部分分开。哦,我的(facepalm)是的,当然标记在
.yrl
文件中用单引号括起来。答案现在是显而易见的。哦,我的(facepalm)是的,当然标记在
.yrl
文件中用单引号括起来。答案现在显而易见。
:~/otp/lib/stdlib/src % cat erl_parse.yrl | grep "':'"
'(' ')' ',' '->' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
spec_fun ->                  atom ':' atom : {'$1', '$3'}.
spec_fun -> atom ':' atom '/' integer '::' : {'$1', '$3', '$5'}.
type -> atom ':' atom '(' ')'             : {remote_type, ?anno('$1'),
type -> atom ':' atom '(' top_types ')'   : {remote_type, ?anno('$1'),
bin_base_type -> var ':' type          : build_bin_type(['$1'], '$3').
bin_unit_type -> var ':' var '*' type  : build_bin_type(['$1', '$3'], '$5').
expr_800 -> expr_max ':' expr_max :
opt_bit_size_expr -> ':' bit_size_expr : '$2'.
bit_type -> atom ':' integer : { element(3,'$1'), element(3,'$3') }.
fun_expr -> 'fun' atom_or_var ':' atom_or_var '/' integer_or_var :
try_clause -> atom ':' expr clause_guard clause_body :
try_clause -> var ':' expr clause_guard clause_body :
inop_prec(':') -> {900,800,900};
:~/otp/lib/stdlib/src % cat erl_parse.yrl | grep "':'" | wc -l
      14
:~/otp/lib/stdlib/src % cat erl_parse.yrl | grep "'#'" 
'(' ')' ',' '->' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
type -> '#' '{' '}'                       : {type, ?anno('$1'), map, []}.
type -> '#' '{' map_pair_types '}'        : {type, ?anno('$1'), map, '$3'}.
type -> '#' atom '{' '}'                  : {type, ?anno('$1'), record, ['$2']}.
type -> '#' atom '{' field_types '}'      : {type, ?anno('$1'),
map_expr -> '#' map_tuple :
map_expr -> expr_max '#' map_tuple :
map_expr -> map_expr '#' map_tuple :
record_expr -> '#' atom '.' atom :
record_expr -> '#' atom record_tuple :
record_expr -> expr_max '#' atom '.' atom :
record_expr -> expr_max '#' atom record_tuple :
record_expr -> record_expr '#' atom '.' atom :
record_expr -> record_expr '#' atom record_tuple :
inop_prec('#') -> {800,700,800};
-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'.
preop_prec('#') -> {700,800}.
-type type_preop() :: '+' | '-' | 'bnot' | '#'.
type_inop_prec('#') -> {800,700,800}.
type_preop_prec('#') -> {700,800}.