我错误地编写了一个方法,该方法将一个变量赋值给方法调用的返回值,该方法调用在以前未定义时将参数传递给参数。我很想知道这是Ruby中的错误,还是实际的预期行为?
public class Timer extends AppCompatActivity {
TextView proba, textViewTimerVrijeme;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
textViewTimerVrijeme = (TextView) findViewById(R.id.textViewTimerVrijeme);
Intent intent = getIntent();
Bundle b = intent.getExtras();
if (b!=null){
String j = (String) b.get("visokiInterval");
textViewTimerVrijeme.setText(j);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_timer, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_pause:
}
return super.onOptionsItemSelected(item);
}
}
答案 0 :(得分:5)
来自David Flanagan的“Ruby编程语言”:
如果已经看到任何先前对变量的赋值,Ruby会将标识符视为局部变量。即使从未执行过该分配,它也会这样做。
这意味着即使在任何代码执行之前,Ruby解析器也会隐式声明变量。只要ruby看到=
运算符,它就会立即生成一个名为yellow
的新变量,其默认值为nil
。然后,当执行该语句时,对该变量的每个引用都共享它的默认值。
本书接着展示了一个类似的,也许是令人惊讶的ruby变量声明行为的例子,类似于:
>> x # NameError: undefined local variable or method `x'
>> x = 0 if false # parsed, but never executed
>> p x # displays nil
此代码的重要性在于表明变量在解析代码后立即声明,并且由于您对yellow
的两个引用发生在同一行,因此必须解析黄色的赋值,因此声明,在作为green
答案 1 :(得分:0)
这种行为虽然令人惊讶,但似乎在包括MRI,JRuby和Rubinius在内的Ruby实现中是一致的。这很可能是解析器将赋值的右侧视为解析为 nil 的表达式的结果。
例如,这会引发一个异常,通知您 blue 为零:
red = 1
blue = red + blue
# TypeError: nil can't be coerced into Fixnum
因为它是一个赋值,解析器似乎隐含地将 blue 声明为nil,然后在右侧将其作为nil值。将其与真正未声明的变量进行对比:
red = 1
blue = red + green
# NameError: undefined local variable or method `green' for main:Object
所以,虽然this answer指向某些相关文档,但它仍然没有真正解释为什么这仅适用于赋值的右侧,然后仅适用于左值在rvalue中隐式声明。由于它在实现中是一致的,因此它似乎是预期的行为,并且可能是语言内部所需要的。
询问为什么Matz和Ruby Core Team设计解析器来处理这个边缘情况对他们来说是一个问题。但实际上,这种语言功能通常会为程序员“做正确的事”。