为什么使用复合表达式?


10

这是我正在阅读的书中的一个示例:

volume = begin
    len = 10
    breadth = 20
    height = 30
    len * breadth * height
end

为什么需要复合表达式?我可以为此编写volume = 10 * 20 * 30volume = len * breadth * height编写一个函数或匿名函数...

为什么要使用beginend?或可能是更好的问题: 我使用它们,因为我想从上面这本书的例子可能不是很好。


1
那是什么书?你们也没有,这个例子不是特别好
Michael K. Borregaard

“学习朱莉娅”,可在此处获得:epdf.pub/learning-julia.html(第127页)
乔治·玛琳

Answers:


4

我想在很多情况下使用begin ... end都很方便,但是正如您所指出的,您通常还可以通过其他构造(例如函数等)获得类似的效果。

有什么能begin ... end块可以用来做什么?

  • 简单地“包含”变量及其名称:lenbreadthheight将仅存在于块中,而不会污染周围的名称空间。
  • 将宏应用于代码块,而不是单个语句。例如,@inbounds begin <all my code without bounds checking goes here> end或将@time begin ... end一段代码包装起来。
  • 在周围的全局范围内创建本地范围(例如,避免全局范围的混乱)。(请注意,正如在评论中已经指出begin ... end没有引入本地范围,但论点成立了类似的let ... end块)。

特别是第二点是我在代码中使用它们的目的。


我也不得不放心,但是begin障碍没有引入范围。另一方面,它们将语句序列转换为表达式,如果使用宏或从宏生成代码,这将很方便。
phipsgabler

1
哦,谢谢,在这方面,我将其与let ... end引入本地范围的混淆了。将纠正我的答案。
crstnbr

我一直都在做出错误的假设:)这正是人们所期望的。
phipsgabler

1
@crstnbr您的第一个项目符号仍然令人误解。似乎仍然说begin块引入了本地范围。
卡梅伦·比加内克

7

概括一下其他人说的话:块允许您将语句列表(无值的语法“短语”,即无法赋值)转换为一个表示值且可以赋值的表达式(“短语”))。

例如,虽然您不应该这样做,但是您可以编写

x = begin
    s = 0
    for i = 1:10
        s += i^2
    end
    s
end

分配x给循环操作的结果。(由于序列中的最后一条语句实际上必须是表达式的限制,否则,该表达式将没有任何值。)

生成此代码的合法用例。例如,您可能会转向

x = @somthing bla blub

进入

x = begin
   (stuff involving bla and blub)
end

对用户透明,而@something可以自由生成任何语言结构。

或者,如果您想编写一个具有更长正文的匿名函数(而不使用function表单):

f = x -> begin
   ...
end

1
稍微说明一下:在Julia中,语句确实具有值并且可以分配。因此,您可以做到x = y = 1a = if false endb = for i in 1:2 end,之后x才有价值1,并且ab都具有价值nothing
Cameron Bieganek

哦,这是分配if-else语句值的更有用的示例:a = if false; 1 else 2 end。在这种情况下,a等于2
卡梅隆·比格涅克

1
是的,它们具有价值,并且在技术上也是表达。赋值是一个表达式,因为它基本上是setproperty!/ setindex!,并且它“具有传统意义”使它具有值(在类似于C的语言中)。与相同if-else,这是多种语言的表达方式。但是for,由于if没有else“默认”值nothing,我认为这只是一个人工产物。
phipsgabler

6

这些块的一种用途是理解:

A = [ begin
           x = y^2
           x - x^2 + 2
         end
         for y = 1:5 ]

您可以创建一个函数并在理解内使用它,但是有时这很方便。每当您想在某处使用多行代码块时(例如,将其作为参数传递给宏(@testset在Test标准库中通常使用)),都可以使用它。


不反对您的观点,但是y^2 - y^4 + 2在这种情况下,您可以写作。也许最好显示一个示例,其中确实需要两个(或更多)步骤。
crstnbr

@crstnbr,您是对的,但我刚开始使用本书中的示例,只是对合理的用法感兴趣。
乔治

1
像这样,省去了两次计算某个昂贵的中间值的麻烦。
phipsgabler

5

简而言之:“开始”仅表示一个代码块(请参见以下文档:https : //docs.julialang.org/en/v1/base/base/#begin)。

在上面的示例中,不清楚使用begin块与声明函数是否有任何价值。

我看不到该关键字在代码中使用率很高,而且我个人从未在实践中使用过它。我的建议是只使用一个函数,因为它会做同样的事情。


我还没有使用过Julia,但这正是我的想法。但是,在设计语言时(大概很聪明),人们一定已经有了一个主意,对吗?
乔治

我同意@logankilpatrick的观点,在很多情况下,您都想使用函数。但是我认为存在这些块的原因(请参阅我的答案)。
crstnbr

@Georgery将语句序列转换为表达式有时是很有用的(参见prognLISP)。
phipsgabler

1
正如您正确指出的那样,在上下文中这似乎是荒谬的
Michael K. Borregaard
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.