You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crystal语言中**(Double splat双星号)的作用与使用方法

Crystal 方法定义与调用中 **(双星号展开)的作用

** 即 double splat(双星号展开),在Crystal中有两类核心用法,结合给出的Shrine上传库代码示例说明如下:

示例参考代码:

class FileImport::AssetUploader < Shrine
  def generate_location(io : IO | UploadedFile, metadata, context, **options)
    name = super(io, metadata, **options)

    File.join("imports", context[:model].id.to_s, name)
  end
end

FileImport::AssetUploader.upload(file, "store", context: { model: YOUR_ORM_MODEL })

1. 方法定义场景:捕获剩余命名参数

在方法定义的参数列表末尾使用**参数名的写法(语法要求该参数必须放在形参列表最后),会自动接收所有调用时传入、未被前面显式声明的形参匹配到的命名参数,统一封装为NamedTuple类型赋值给**后命名的变量。

  • 对应示例中generate_location方法的**options:Shrine父类的generate_location原生支持多个可选命名参数(比如自定义文件名、扩展名处理规则等),子类重写方法时不需要把所有可选参数逐一在形参里列全,靠**options就能把所有额外传入的命名参数全部接住,不会触发参数不匹配的编译错误。

2. 方法调用场景:展开键值对为命名参数

在调用方法传参时,给键类型匹配的NamedTuple/Hash类型变量前加**,会把变量内的所有键值对展开为独立的命名参数传入目标方法。

  • 对应示例中super(io, metadata, **options)的写法:调用父类同名原始实现时,不需要把options里存储的每个键值对手动拆分逐一传参,用**options就能把之前捕获到的所有额外命名参数原封不动透传给父类逻辑,既不会漏传参数,也省掉了大量冗余的参数透传代码。

这种写法在重写框架方法的场景下兼容性极强:哪怕后续框架版本给父类方法新增了可选命名参数,子类重写的逻辑不需要做任何修改,就能自动接收、透传新参数,不会出现参数匹配报错。示例最后调用upload方法时传入的context: { model: YOUR_ORM_MODEL }就是普通命名参数传参,这个值会沿着Shrine的内部调用链传到generate_location的context形参中,供自定义路径逻辑拼接模型ID使用。

内容的提问来源于stack exchange,提问作者learncodes123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:24:14