Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Julia函数的参数_Julia - Fatal编程技术网

Julia函数的参数

Julia函数的参数,julia,Julia,有人知道为什么Julia选择了一种不能修改输入参数的函数设计吗?如果我们想使用它,这需要通过一个非常人工的过程,以一个可笑的单元素表的形式表示这些数据 Ada也有同样的限制,在2012年的重新设计中放弃了它,用户非常满意。一个小的关键字(如Ada中的out)很可能表明需要在输出中保留对参数的修改。根据我在Julia中的经验,理解值和绑定之间的差异是很有用的 价值观 Julia中的每个值在内存中都有一个具体的类型和位置。值可以是可变的或不可变的。特别是在定义自己的复合类型时,您可以决定此类型的对象

有人知道为什么Julia选择了一种不能修改输入参数的函数设计吗?如果我们想使用它,这需要通过一个非常人工的过程,以一个可笑的单元素表的形式表示这些数据


Ada也有同样的限制,在2012年的重新设计中放弃了它,用户非常满意。一个小的关键字(如Ada中的out)很可能表明需要在输出中保留对参数的修改。

根据我在Julia中的经验,理解值和绑定之间的差异是很有用的

价值观 Julia中的每个值在内存中都有一个具体的类型和位置。值可以是可变的或不可变的。特别是在定义自己的复合类型时,您可以决定此类型的对象是可变的(
mutable struct
)还是不可变的(
struct

当然,Julia有内置类型,其中一些是可变的(例如数组),另一些是不可变的(例如数字、字符串)。当然,它们之间存在着设计上的权衡。在我看来,不变价值观的两大好处是:

  • 如果编译器使用不可变的值,它可以执行许多优化来加速代码
  • 用户可以确保将不可变项传递给函数不会改变它,这样的封装可以简化代码分析
  • 但是,特别是,如果您想在可变包装器中包装一个不可变的值,标准方法是使用
    Ref
    如下所示:

    julia> x = Ref(1)
    Base.RefValue{Int64}(1)
    
    julia> x[]
    1
    
    julia> x[] = 10
    10
    
    julia> x
    Base.RefValue{Int64}(10)
    
    julia> x[]
    10
    
    您可以将这些值传递给函数并在其中修改它们。当然,
    Ref
    引入了一种不同的类型,因此方法实现必须有所不同

    变量 变量是绑定到值的名称。一般来说,除了一些特殊情况,如:

  • 从模块
    B
    中的模块
    a
    重新绑定变量
  • 重新定义一些常量,例如尝试用非函数值重新分配函数名
  • 将具有指定类型的允许值的变量与无法转换为该类型的值重新绑定 您可以重新绑定变量以指向任何您想要的值。大多数情况下,使用
    =
    或某些特殊构造(如
    for
    let
    catch
    语句)执行重新绑定

    现在-到达点-函数被传递一个值,而不是绑定。您可以修改函数参数的绑定(换句话说:您可以重新绑定参数所指向的值),但此参数是一个新变量,其范围位于函数内部

    例如,如果我们想要一个电话,比如:

    x = 10
    f(x)
    
    更改变量
    x
    的绑定是不可能的,因为
    f
    甚至不知道
    x
    的存在。它只传递其值。特别是,正如我在上面所提到的,添加这样一个功能将打破规则,即模块
    a
    不能从模块
    B
    重新绑定变量,因为
    f
    可能在不同于定义
    x
    的模块中定义

    怎么办 事实上,根据我的经验,在没有此功能的情况下工作非常容易:

  • 我通常只需从我分配给变量的函数返回一个值。在Julia中,这很容易,因为元组解包语法,例如
    x,y,z=f(x,y,z)
    ,其中
    f
    可以定义为
    f(x,y,z)=2x,3y,4z
  • 您可以使用在代码执行之前展开的宏,因此可以修改变量的绑定,例如,
    macro plusone(x)return esc(:($x=$x+1))end
    现在写入
    y=100@plusone(y)
    将更改
    y
    的绑定
  • 最后,您可以使用上面讨论过的
    Ref
    (或任何其他可变包装器,如您在问题中所指出的)
  • Schemer问道:“有人知道为什么Julia选择了一种不能修改输入参数的函数设计吗?”

    你的问题是错误的,因为你假设了错误的事情

  • 参数是变量
  • 当您将内容传递给函数时,这些内容通常是值而不是变量

    例如:

    function double(x::Int64)
      2 * x
    end
    
    现在,当你使用

    double(4)
    
    函数修改其参数x的意义是什么,它是无意义的。此外,函数不知道如何调用它

    此外,Julia专为速度而生。

    修改其参数的函数将很难优化,因为它会产生副作用。副作用是当程序/函数更改其范围之外的对象/事物时

    如果函数不修改作为其调用参数一部分的变量,那么您可以放心地知道

  • 变量的值不会更改
  • 该功能的结果可以优化为常数
  • 不调用函数不会破坏程序的行为
  • 这三个因素使得功能性语言快速而非功能性语言缓慢

    此外,当您进入并行编程或多线程编程时,您绝对不希望在您(程序员)不知道的情况下更改变量的值


    “您将如何使用建议的宏实现函数F(x),该函数返回一个布尔值并通过c:=c+1修改c。F可用于以下Ada代码:c:=0;而F(c)循环…结束循环;”Schemer询问

    我会写

    function F(x)
      boolean_result = perform_some_logic()
      return (boolean_result,x+1)
    end
    
    flag = true
    c = 0
    (flag,c) = F(c)
    while flag
      do_stuff()
      (flag,c) = F(c)
    end
    
    function F(x)
      boolean_result = perform_some_logic()
      if boolean_result == true
          return (true,x+1)
      else
          return (false,0)
      end
    end
    
    flag = true
    c = 0
    (flag,c) = F(c)
    while flag
      do_stuff()
      (flag,c) = F(c)
    end
    

    “不幸的是,没有,因为,我应该说,当F返回值False时,c必须再次取值0(c随着循环寿命的延长而增加,当循环死亡时返回0)。”Schemer说

    然后我会写信

    function F(x)
      boolean_result = perform_some_logic()
      return (boolean_result,x+1)
    end
    
    flag = true
    c = 0
    (flag,c) = F(c)
    while flag
      do_stuff()
      (flag,c) = F(c)
    end
    
    function F(x)
      boolean_result = perform_some_logic()
      if boolean_result == true
          return (true,x+1)
      else
          return (false,0)
      end
    end
    
    flag = true
    c = 0
    (flag,c) = F(c)
    while flag
      do_stuff()
      (flag,c) = F(c)
    end
    
    虽然你问为什么,但你问题中的“什么”不是