很抱歉,如果这个问题是重复的。但我无法找到使用上的差异。当我运行以下代码时,我得到了不同的答案。我从大多数教程中看到使用" do ... end"与" {...}"相同块。
include Comparable
a = [1, 4, 2, 3, 5]
p a.sort do |x,y|
y <=> x
end
输出显示为= [1,2,3,4,5]
但是当我这样跑的时候......
include Comparable
a = [1, 4, 2, 3, 5]
p a.sort { |x,y|
y <=> x
}
输出显示为= [5,4,3,2,1]
这里出了什么问题。是否存在两种语法有任何不同行为的情况?
答案 0 :(得分:5)
优先顺序不同。第一个被解释为
p (a.sort) do
...
end
由于该块未传递给sort
,因此将按默认的升序排序。然后,块传递给p
,public class IngoingReceiver extends BroadcastReceiver {
int previousState = 2;
public void onReceive(final Context context, Intent intent) {
ITelephony telephonyService;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(tm);`enter code here`
Bundle bundle = intent.getExtras();
String phoneNumber = bundle.getString("incoming_number");
Log.e("INCOMING", phoneNumber);
if ((phoneNumber != null)) {
telephonyService.silenceRinger();
telephonyService.endCall();
Log.e("HANG UP", phoneNumber);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.android.internal.telephony;
public interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
不使用它。
答案 1 :(得分:3)
sawa的答案是正确的,但由于OP要求更多澄清,我正在提供我自己的答案。
所有这四个方法调用都表现相同,将块传递给foo
方法:
foo { ... }
foo do ... end
foo() { ... }
foo() do ... end
当您编写两个方法和一个块时,参数周围没有括号,不清楚该块使用哪种方法:
foo bar { ... }
foo bar do ... end
问题是:“我是否将一个块传递给bar
,然后将其返回值传递给foo
?或者我使用foo
作为bar
调用# Passing a block to `bar`, and then passing the result to `foo`
foo( bar { ... } )
foo( bar do ... end )
# Passing an argument and block to `foo`
foo( bar ) { ... }
foo( bar ) do ... end
争论并传递一个块?“
使用括号,您可以使用块样式清除它:
{…}
您遇到的do…end
和# Passing a block to `bar`, and then passing the result to `foo`
foo bar{ ... }
foo( bar do ... end )
# Passing an argument and block to `foo`
foo bar do ... end
foo( bar ){ ... }
之间的区别在于Ruby选择在省略括号时放置括号。两个块符号具有不同的优先级,因此您以不同的结果结束:
# This code…
p a.sort do |x,y|
y <=> x
end
# …is the same as this code:
b = a.sort
p(b){ |x,y| y <=> x }
# Note that you are passing a block to the `p` method
# but it doesn't do anything with it. Thus, it is
# functionally equivalent to just:
p a.sort
所以,特别是在你的情况下:
# This code…
p a.sort { |x,y|
y <=> x
}
# …is functionally the same as this code:
b = a.sort{ |x,y| y <=> x }
p b
和
def foo(a=nil)
yield :foo if block_given?
end
def bar
yield :bar if block_given?
:bar_result
end
foo bar { |m| puts "block sent to #{m}" }
#=> block sent to bar
#=> foo got :bar_result
foo( bar do |m| puts "block sent to #{m}" end )
#=> block sent to bar
#=> foo got :bar_result
foo( bar ){ |m| puts "block sent to #{m}" }
#=> foo got :bar_result
#=> block sent to foo
foo bar do |m| puts "block sent to #{m}" end
#=> foo got :bar_result
#=> block sent to foo
最后,如果你仍然没有得到它,也许深入考虑以下代码和输出将有所帮助:
{…}
请注意,上面代码中的第一个和最后一个示例的区别仅在于它们是否使用do…end
或os.getcwd()
。
答案 2 :(得分:2)
正如其他人所指出的,两种类型的块之间的优先级存在差异。但是,优先权并没有真正影响它在实践中的使用方式。
有些Rubyist会关注Weirich Convention,named so by Avdi Grimm。
简而言之,一个使用另一个是基于它是否正常(使用返回值),在这种情况下使用{ ... }
,还是程序性的(以某种方式改变系统的状态或执行输出),在这种情况下使用do ... end
。