有没有办法将依赖字段传递给Julia结构?

有没有办法将依赖字段传递给Julia结构?,julia,Julia,我试图在Julia中编写一个数据加载器,并在其上定义一些附加方法 用户可以通过两种方式加载数据—“远程”和“本地” 如果用户选择local,我需要另一个字段base\u dir——存储数据的目录。如果用户选择remote,我不需要base\u dir,因为我知道向哪个URL发出请求 之后,定义加载程序后,我将调用加载程序上的一些函数来执行其他操作(下面的函数示例): 我的问题是如何在结构中定义这种相关性?也就是说,如何告诉用户并在代码中实现逻辑,如果getter是local我需要base\u

我试图在Julia中编写一个数据加载器,并在其上定义一些附加方法

用户可以通过两种方式加载数据—“远程”和“本地

如果用户选择
local
,我需要另一个字段
base\u dir
——存储数据的目录。如果用户选择
remote
,我不需要
base\u dir
,因为我知道向哪个URL发出请求

之后,定义加载程序后,我将调用加载程序上的一些函数来执行其他操作(下面的函数示例):


我的问题是如何在结构中定义这种相关性?也就是说,如何告诉用户并在代码中实现逻辑,如果getter是
local
我需要
base\u dir
,如果它是远程的,我可以从我的结构中动态删除字段
base\u dir


我是Julia的新手,因此任何关于改进代码的其他建议都将非常受欢迎。

我认为有几种方法可以做到这一点;在我看来,最简单的方法就是依赖调度器。这围绕使用两个结构展开,一个用于“本地”,一个用于“远程”。如果真的需要,您可以创建一个它们都属于的“AbstractLoader”,并在最后介绍更多内容

function bar(x::DataLoader)
    if x.getter == "local"
        #do_somethings
        println("local found")

    elseif x.getter == "remote"
        println("remote found")

    else
        println("wrong mode passed")
        
    end  
end
我认为这种逻辑有几个优点:

  • 对于开发人员:这两种方法可以独立开发
  • 对于开发人员:您不必在代码中放置一些保持简单的“如果”逻辑。(不可能通过无效模式)。换句话说:你不必实现调度器,因为你依赖于Julia的调度器
  • 它向用户阐明了API:当用户想要一个本地对象时,必须传递一个字符串。当用户需要远程设备时,他/她不能传递额外的参数
主要缺点是代码重复。如果存在一些代码重复,那么可以进行反击,要做到这一点,您需要使这两个结构属于一个抽象类型

这将以以下方式更改代码:

struct LocalLoader 
    basedir::String
end

struct RemoteLoader 
end

ll = LocalLoader("test_directory")
rl = RemoteLoader()

function bar(ll::LocalLoader)
    println("Base directory is $(ll.basedir)")
end

function bar(rl::RemoteLoader)
    println("This is the remote loader")
end

bar(ll)
bar(rl)
抽象类型AbstractLoader end

struct LocalLoader您应该有一个抽象类型
DataLoader
和两个具体结构
DataLoaderLocal
DataLoaderRemote
。这正是应该使用类型系统而不是某些“特殊”字段的情况。您也可以始终使用一个工厂,例如
get\u data\u loader
,返回
DataLoader
的任意一个版本。谢谢您的回答,这肯定会有所帮助。由于我的Python背景,我更倾向于使用一个加载程序,但根据用户选择的模式不同,情况也不同,但我想这是一种更“朱利安”的设计模式。我很高兴它有所帮助。祝你有愉快的一天。
function bar(x::DataLoader)
    if x.getter == "local"
        #do_somethings
        println("local found")

    elseif x.getter == "remote"
        println("remote found")

    else
        println("wrong mode passed")
        
    end  
end
struct LocalLoader 
    basedir::String
end

struct RemoteLoader 
end

ll = LocalLoader("test_directory")
rl = RemoteLoader()

function bar(ll::LocalLoader)
    println("Base directory is $(ll.basedir)")
end

function bar(rl::RemoteLoader)
    println("This is the remote loader")
end

bar(ll)
bar(rl)
abstract type  AbstractLoader end

struct LocalLoader <: AbstractLoader
    basedir::String
end

struct RemoteLoader <: AbstractLoader
end

ll = LocalLoader("test_directory")
rl = RemoteLoader()

function bar(ll::LocalLoader)
    println("Base directory is $(ll.basedir)")
end

function bar(rl::RemoteLoader)
    println("This is the remote loader")
end

bar(ll)
bar(rl)

function foo(al::AbstractLoader)
    println("Do common tasks")
end

foo(ll)
foo(rl)