Julia基于命名参数的多重分派?

Julia基于命名参数的多重分派?,julia,Julia,我正在尝试创建灵活的功能,允许多种用途: save(image_url = "http://...") save(image_url = "http://...", title = "Cats", id = "cats") save(text = "Some text", comments = "Some comments") save(text = "Another text", title = "News", compression = true) 基本上,它由3个(或更多)功能组合而成(

我正在尝试创建灵活的功能,允许多种用途:

save(image_url = "http://...")
save(image_url = "http://...", title = "Cats", id = "cats")
save(text = "Some text", comments = "Some comments")
save(text = "Another text", title = "News", compression = true)
基本上,它由3个(或更多)功能组合而成(
save\u image\u url
save\u image\u path
save\u text

它们都有3个相同的可选参数
title
description
compression
。每个都可以有任意数量的特定参数

我不想使用位置参数,因为很难记住参数的顺序。此外,第一个参数对于
image\u url
image\u path
text
具有相同的
String
类型

不幸的是,多分派似乎对命名参数不起作用。那么,处理此类案件的模式是什么

执行不起作用

function save(;
  image_url::   String,

  title::       Union{String, Nothing} = nothing,
  description:: Union{String, Nothing} = nothing,
  compression:: Union{Bool, Nothing}   = nothing
)::Nothing
  nothing
end


function save(;
  image_path::  String,

  title::       Union{String, Nothing} = nothing,
  description:: Union{String, Nothing} = nothing,
  compression:: Union{Bool, Nothing}   = nothing
)::Nothing
  nothing
end

function save(;
  text::        String,
  comments::    Union{String, Nothing} = nothing,

  title::       Union{String, Nothing} = nothing,
  description:: Union{String, Nothing} = nothing,
  compression:: Union{Bool, Nothing}   = nothing
)::Nothing
  nothing
end

我建议如下拆分用户界面和实现细节:

function save(;
    image_url=nothing,
    image_path=nothing,
    text=nothing,

    title=nothing,
    description=nothing,
    compression=nothing
)
    save(image_url, image_path, text, title, description, compression)
end

function save(image_url::String, ::Nothing, ::Nothing, title, description, compression)
    # do something
end

function save(::Nothing, image_path::String, ::Nothing, title, description, compression)
    # do something
end

function save(::Nothing, ::Nothing, text::String, title, description, compression)
    # do something
end

function save(image_url, image_path, text, title, description, compression)
    @error "only one of image_url, image_path, text are acceptable"
end

当事情变得太复杂时,您总是可以从关键字参数创建一个新的结构,并使用traits分派它。

多重分派很好,但它有时是用于作业的错误工具。在这种情况下,函数名的基本分派是简单而充分的。如果可能的话,我更喜欢这个选项。但是,如果需要一致的函数名,则始终可以对自定义类型进行分派

不同的函数名 自定义类型 通过立即创建要分派的对象,您可以在呼叫站点明确分派:

save(ImageURL("https://..."); title="SomeTitle")

谢谢,可以为splat提供打字吗?像
函数save(url::ImageURL;kwargs…::OptionalArgsType)
你可以做例如
kwargs::Int…。
如果你希望它们都是
Int
不幸的是,关键字参数不参与分派。原因是,如果你使用一堆关键字参数,它被判断为可能会在方法中产生组合爆炸。例如,
f(;a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8)
将具有
9!=362880
不同的方法。哎呀!
struct ImageURL
   val::String
end

function save(url::ImageURL; kwargs...)
    handle_metadata(; kwargs...)
    # url specific code
end

function handle_general_options(; title=nothing, description=nothing)
    # shared code
end
save(ImageURL("https://..."); title="SomeTitle")