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