为什么Julia中的字符串宏使用...?

4
我正在查看Julia的r_str宏的源代码,该宏将r"text"解析为Regex("text")。第二个参数是flags...,用于传递正则表达式标志,如不区分大小写的i等。我自己试了一下,得到了:
julia> macro a_str(p, flags...)
           print(flags)
           p
       end

julia> a"abc"iii
("iii",)"abc"

所以看起来iii作为第一个标志全部传递了进去。在这种情况下,为什么标志上会有...?是否可以将多个flags元素传递给宏?

3个回答

9
当最初提出这个问题时,宏扩展器(即使用macro关键字定义的函数,用于将传递给宏的表达式转换为单一输出表达式)不是一个通用函数,而是匿名函数,这在Julia 0.4及以前的版本中是一种不同类型的函数。此时,编写一个匿名函数签名,可以同时适用于一个或两个参数的唯一方法是使用尾随可变参数,因此使用这种模式来定义字符串宏。在Julia 0.5中,所有函数都变成了通用函数,包括匿名函数和宏扩展器。因此,现在可以以多种方式编写宏,包括使用字符串参数后的旧方式:
# old style
macro rm_str(raw, rest...)
    remove = isempty(rest) ? "aeiouy" : rest[1]
    replace(raw, collect(remove), "")
end

# new style with two methods
macro rm_str(raw)
    replace(raw, ['a','e','i','o','u','y'], "")
end
macro rm_str(raw, remove)
    replace(raw, collect(remove), "")
end

# new style with default second argument
macro rm_str(raw, remove="aeiouy")
    replace(raw, collect(remove), "")
end

这些都会导致相同的非标准字符串字面量行为:

julia> rm"foo bar baz"
"f br bz"

julia> rm"foo bar baz"abc
"foo r z"

字符串字面量会从中删除标记的字符,其中默认情况下会删除所有ASCII元音字母(“aeiouy”)。在这种情况下,使用第二个具有默认值的参数的新方法是最简单和最清晰的方法,就像在许多情况下一样,但现在可以根据情况使用任何最佳方法。


3

通过显式调用,例如:

@a_str("abc", "iii", "jjj")

您可以传递多个标志。但是我不知道如何使这与a"abc"ijk语法一起工作。


2

将其更改为允许它(如何实现?)或更改为不在正则表达式示例中使用“...”? - asmeurer
修改代码,不再使用“...”。它可能曾经有用过,但现在看起来已经不再需要了。 - IainDunning

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接