Julia 有没有一种方法可以在函数中使用;已定义(:x)“;,其中x在同一函数中定义?

Julia 有没有一种方法可以在函数中使用;已定义(:x)“;,其中x在同一函数中定义?,julia,Julia,我有一个函数,它在工作目录的父目录中查找名为“global”的文件。这就是我的想象: function readglobal() if isfile("./global") text = readdlm("./global",String,comment_char='/') else for i = 1:8 if isfile("../"^i * "global") text = readdlm("../"^i * "global",Strin

我有一个函数,它在工作目录的父目录中查找名为“global”的文件。这就是我的想象:

function readglobal()
  if isfile("./global")
    text = readdlm("./global",String,comment_char='/')
  else
    for i = 1:8
      if isfile("../"^i * "global")
        text = readdlm("../"^i * "global",String,comment_char='/')
        break
      end
    end
  end

  isdefined(:text) || error("Could not find global file")

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end
这不起作用,因为isdefined在当前的_module()中查找全局变量,我从中调用函数。 有没有办法让它按预期工作?在函数中定义(:text)来求值


我用下面的代码解决了这个问题,但我认为上面的代码更简洁

function readglobal()
  foundit = isfile("./global")
  if foundit
    text = readdlm("./global",String,comment_char='/')
    foundit=true
  else
    for i = 1:8
      foundit = isfile("../"^i * "global")
      if foundit
        text = readdlm("../"^i * "global",String,comment_char='/')
        break
      end
    end
  end

  foundit || error("Could not find global file")

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end

以下是此功能的1.5行版本:

readglobal() = Dict(mapslices(x->=>(x...),readdlm(first(filter(isfile,
  "./$("../"^i)global" for i=0:8)),String;comment_char='/'),2))
function get_global_content()
    if isfile("./global")
      return readdlm("./global",String,comment_char='/')
    else
      for i = 1:8
        if isfile("../"^i * "global")
          return readdlm("../"^i * "global",String,comment_char='/')
        end
      end
    end
    error("Could not find global file")
end

function readglobal()
  text = get_global_content()

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end

如果文件丢失,它甚至会返回一个错误;)

以下是此功能的1.5行版本:

readglobal() = Dict(mapslices(x->=>(x...),readdlm(first(filter(isfile,
  "./$("../"^i)global" for i=0:8)),String;comment_char='/'),2))
function get_global_content()
    if isfile("./global")
      return readdlm("./global",String,comment_char='/')
    else
      for i = 1:8
        if isfile("../"^i * "global")
          return readdlm("../"^i * "global",String,comment_char='/')
        end
      end
    end
    error("Could not find global file")
end

function readglobal()
  text = get_global_content()

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end

如果文件丢失,它甚至会返回一个错误;)

编辑:不知何故,我错过了您找到的解决方法,正如您所说的,这与我建议的差不多。我不同意第一个代码更干净的说法,使用
isdefined
对我来说似乎有点黑客味。IMHO,
foundit
标志是正确的方法

原始答案: 不要使用
isdefined
检查文件是否已找到。而是设置一个标志,例如
filefound
。以下内容(警告,未经测试):

编辑2:这里有一个变体:

function readglobal(filename, maxtries=8)
    tries = 0
    while !isfile(filename) && (tries+=1) <= maxtries
        filename = joinpath("..", filename)
    end
    tries > maxtries || error("Could not find file ")

    text = readdlm(filename, ...
    ...
end
函数readglobal(文件名,maxtries=8) 尝试=0 虽然isfile(文件名)&&(trys+=1)Maxtrys | |错误(“找不到文件”) text=readdlm(文件名。。。 ... 终止
编辑:不知何故,我错过了你找到的解决方法,正如你所说的,这与我建议的差不多。我不同意第一个代码更干净,使用
定义的
对我来说似乎有点黑客味。一个
foundit
标志是正确的方法,IMHO

原始答案: 不要使用
isdefined
检查文件是否已找到。而是设置一个标志,例如
filefind
。类似于以下内容的内容(警告,未测试):

编辑2:这里有一个变体:

function readglobal(filename, maxtries=8)
    tries = 0
    while !isfile(filename) && (tries+=1) <= maxtries
        filename = joinpath("..", filename)
    end
    tries > maxtries || error("Could not find file ")

    text = readdlm(filename, ...
    ...
end
函数readglobal(文件名,maxtries=8) 尝试=0 while!isfile(filename)&&(tries+=1)maxtries | |错误(“找不到文件”) text=readdlm(文件名。。。 ... 终止
答案不准确,但我会使用一个单独的函数:

readglobal() = Dict(mapslices(x->=>(x...),readdlm(first(filter(isfile,
  "./$("../"^i)global" for i=0:8)),String;comment_char='/'),2))
function get_global_content()
    if isfile("./global")
      return readdlm("./global",String,comment_char='/')
    else
      for i = 1:8
        if isfile("../"^i * "global")
          return readdlm("../"^i * "global",String,comment_char='/')
        end
      end
    end
    error("Could not find global file")
end

function readglobal()
  text = get_global_content()

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end
或者,查看
可为空的
,例如

function readglobalnull()
  text = Nullable()
  if isfile("./global")
    text = Nullable(readdlm("./global",String,comment_char='/'))
  else
    for i = 1:8
      if isfile("../"^i * "global")
        text = Nullable(readdlm("../"^i * "global",String,comment_char='/'))
        break
      end
    end
  end

  isnull(text) && error("Could not find global file")
  text = get(text)

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end

这不是一个确切的答案,但我会使用一个单独的函数:

readglobal() = Dict(mapslices(x->=>(x...),readdlm(first(filter(isfile,
  "./$("../"^i)global" for i=0:8)),String;comment_char='/'),2))
function get_global_content()
    if isfile("./global")
      return readdlm("./global",String,comment_char='/')
    else
      for i = 1:8
        if isfile("../"^i * "global")
          return readdlm("../"^i * "global",String,comment_char='/')
        end
      end
    end
    error("Could not find global file")
end

function readglobal()
  text = get_global_content()

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end
或者,查看
可为空的
,例如

function readglobalnull()
  text = Nullable()
  if isfile("./global")
    text = Nullable(readdlm("./global",String,comment_char='/'))
  else
    for i = 1:8
      if isfile("../"^i * "global")
        text = Nullable(readdlm("../"^i * "global",String,comment_char='/'))
        break
      end
    end
  end

  isnull(text) && error("Could not find global file")
  text = get(text)

  dict = Dict{String,String}()
  for i in 1:size(text)[1]
    dict[text[i,1]] = text[i,2]
  end
  return dict
end

Julia的0.7版有一个
@isdefined variable\u name
宏,可以精确地执行我在这个问题中要求的操作。它应该适用于任何局部变量。

Julia的0.7版有一个
@isdefined variable\u name
宏,可以精确地执行我在这个问题中要求的操作。它应该适用于任何局部变量变量。

Wow,我没有意识到
joinpath
有多慢!它似乎比我想象的做得更多。但是,以增量方式构建
filepath
变量比在每次迭代时完整地生成变量更干净。我想你是对的,
isdefined
的这种用法很粗糙,而且标志更适合y、 但我仍然认为,在某些情况下,
isdefined
在调用它的范围内寻找符号赋值是很好的,在这种情况下是函数。关于以增量方式生成路径:这真的有区别吗?在我看来,既然字符串是不可变的,就没有“递增”字符串,因为每次创建一个新字符串。我猜对了吗?也许克服这一问题的一种方法是首先创建最大的字符串并在其上使用子字符串。“递增”是指每次迭代执行一次
file=“../”*file
,而不是
。/“*file
,然后
”/^2*文件
,…,然后是
。/^n*file
。当
n=8
时,性能差异很小,但第一种方式是线性扩展的,而您的方式是指数扩展的。我还发现前者更优雅。不幸的是,我无法回答您关于
定义的实际问题,对此表示抱歉。哇,我没有意识到
joinpath
有多慢!看起来很像s做的比我想象的要多得多。虽然以增量方式构建
文件路径
变量比在每次迭代时完整地生成变量更为简洁。我认为你是对的,
的这种用法被定义为
,而且标志更合适。但我仍然认为在某些情况下,它对
I可能有好处sddefine
在调用它的范围内查找符号赋值,在本例中是函数。关于增量生成路径:这真的有区别吗?在我看来,既然字符串是不可变的,就没有“增量”这样的东西字符串,因为每次创建一个新的字符串。我猜对了吗?也许克服这个问题的一种方法是先创建最大的字符串,然后在其上使用子字符串。所谓“增量”是指每次迭代执行一次
文件=“../”*文件
”,而不是
。/“*文件
,然后
。/”^2*文件
,…,然后
。/”^n*file
。当
n=8
时,性能差异很小,但第一种方式是线性扩展的,而您的方式是指数扩展的。我还发现前者更优雅。遗憾的是,我无法回答您关于
定义的实际问题,对此表示抱歉。