YARD如何标注块参数类型?能否避免为类型标注创建临时变量?
YARD块参数无临时变量类型标注方案
完全不需要创建临时变量即可实现块参数类型标注,让LSP正常识别类型提供自动补全,常用方案有以下几种:
- 块内直接用
@param标注对应参数类型
这是兼容性最好的写法,适配所有支持YARD类型解析的Ruby LSP,只需要在块内部第一行紧贴参数的位置标注参数类型即可,直接使用原块参数就能获得补全:
注意标注需要放在块的最开头,和块参数行之间不要留空行,否则部分旧版本LSP会识别失败。foos.each_with_object(Set.new) do |foo, obj| # @param obj [Set] # @param foo [Foo] # 直接操作obj即可获得Set类型的自动补全,无需额外赋值临时变量 obj.add(foo) end - 行内参数标注(不推荐)
如果追求极致的代码紧凑度,可以直接在块参数列表内通过注释标注类型,不需要单独占行,但可读性较差:foos.each_with_object(Set.new) do |foo, # @type [Foo] obj # @type [Set] | obj.add(foo) end - 依赖类型推断省略手动标注
目前新版本的Ruby LSP、Solargraph都已经内置了Ruby核心库、标准库的泛型类型签名,对于each_with_object这类内置方法,只要传入的初始对象类型明确(比如明确传入Set.new而非无类型的动态变量),LSP可以自动推断出块参数的类型,完全不需要手动写任何类型注释。
如果是自定义方法,可以在方法定义处通过@yieldparam提前声明块参数类型,所有调用位置都不需要重复标注:# 方法定义时提前标注块参数类型 # @yieldparam item [User] # @yieldparam memo [Set<Integer>] def iterate_users(users, &block) users.each_with_object(Set.new, &block) end # 调用时无需任何注释,LSP自动识别参数类型 iterate_users(users) do |user, id_set| id_set.add(user.id) end
早期LSP类型推断能力不足时,才需要通过给临时变量加@type赋值的方式绕路实现类型提示,新版本工具链下已经完全不需要这种冗余写法。
内容的提问来源于stack exchange,提问作者Nikita Fedyashev
相关产品推荐
相关产品推荐

