如何在Julia中创建带参数的非标准字符串字面量?
解决方案
要实现支持任意整数参数的非标准字符串字面量,核心要理解Julia对RN"str"这类语法的解析规则:它会被自动转换为调用RN_str("str")宏。因此我们需要动态生成对应任意整数N的RN_str宏,以下提供两种可行方案:
方案1:手动生成指定整数的宏
如果你只需要支持特定几个整数,可以写一个宏生成函数,按需生成对应宏:
function rotate(shift_amount::Int64, s::String) shift = shift_amount ≤ length(s) ? shift_amount : shift_amount % length(s) return s[end-shift+1:end] * s[1:end-shift] end # 定义宏生成函数 function generate_rot_macro(n::Int) macro_name = Symbol("R$(n)_str") # 避免重复生成 if !@isdefined($macro_name) @eval begin macro $macro_name(s) rotate($n, s) end end end end # 生成需要的宏 generate_rot_macro(1) generate_rot_macro(244) generate_rot_macro(-5) # 支持负数偏移
使用示例:
R1"abc" # 输出 "bca" R244"abc" # 244 % 3 = 1,输出 "bca" R-5"abc" # -5 % 3 = 1,输出 "bca"
方案2:自动生成任意整数的宏
如果需要支持任意整数(无需预先声明),可以利用Julia的Base.getproperty机制,在首次调用未定义的RN_str宏时自动生成它:
module RotStrModule export rotate function rotate(shift_amount::Int64, s::String) shift = shift_amount ≤ length(s) ? shift_amount : shift_amount % length(s) return s[end-shift+1:end] * s[1:end-shift] end # 拦截模块属性获取,自动生成RN_str宏 function Base.getproperty(mod::Module, name::Symbol) name_str = string(name) # 匹配以R开头、以_str结尾的符号 if startswith(name_str, "R") && endswith(name_str, "_str") # 提取中间的数字部分 num_str = replace(name_str, r"^R|_str$" => "") if tryparse(Int, num_str) !== nothing n = parse(Int, num_str) macro_name = name # 动态生成宏 @eval mod begin macro $macro_name(s) rotate($n, s) end end # 返回生成的宏 return getfield(mod, macro_name) end end # 非目标符号,按默认逻辑处理 return getfield(mod, name) end end # module
使用示例:
using .RotStrModule R123"hello" # 123 % 5 = 3,输出 "lohel" R-7"hello" # -7 %5 = 3,输出 "lohel" R9999"test" # 9999%4=3,输出 "ttes"
这个方案的优势是无需预先声明任何整数,首次调用任意RN"str"时会自动生成对应的宏,后续调用直接复用已生成的宏,性能无影响。
内容的提问来源于stack exchange,提问作者Flavio Barros
相关产品推荐
相关产品推荐

