猜猜这个编译的结果是什么?
import scala.util.parsing.combinator._
object ExprParser extends JavaTokenParsers {
lazy val literal = int
lazy val int = rep("0")
}
编译器说int
is recursive and asks for the type of it。我的实验说,递归的核心隐藏在文字的声明中!删除它,你会看到递归消失了!
答案 0 :(得分:5)
此处JavaTokenParsers
定义了名为literal
的内容。
而rep("0")
实际上是rep(literal("0"))
(literal
是从String
到Parser[String]
的隐式转换。
但是literal
中的JavaTokenParsers
需要参数,而你的int
没有。所以你可能会期望你的只是重载,而不是覆盖,并且不存在冲突 - literal
和object ExprParser extends JavaTokenParsers {
lazy val literal: Parser[List[String]] = int
lazy val int: Parser[List[String]] = rep("0")
}
之间没有相互递归。
事实上,如果你提供显式类型:
literal
这对编译器来说很好。
那么为什么在省略返回类型时会触发递归的显式返回类型规则?
我认为这是一个相当微妙的问题。我不确定我确切知道这里发生了什么。我在Scala语言规范中找不到涵盖它的特定语言。
我最好的猜测是,在触发显式返回类型规则时,编译器仍然处于相对较早的阶段,它尚未准确地解决了什么或不是重载或覆盖。还没有返回类型,它必须基于有关类型的部分信息继续进行。
但它确实知道您对int
的定义涉及名称int
,而您对literal
的定义涉及名称static class BluetoothInHandler extends Handler {
private final WeakReference<Bluetooth_dataDisplay> mActivity;
BluetoothInHandler(Bluetooth_dataDisplay activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
//change 3
Log.e("test","handleMessage");
final Bluetooth_dataDisplay thizz = mActivity.get();
if (thizz == null) return;
if (msg.what == thizz.handlerState) {
String readMessage = (String) msg.obj;
thizz.myLabel.setText(readMessage);
}
}//end of handle message
}//end of Bluetoothin handler
@Override
public void onResume() {
super.onResume();
String MAC = getIntent().getStringExtra("MAC");
mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice bluetoothDevice = mAdapter.getRemoteDevice(MAC);
ConnectingThread t = new ConnectingThread(bluetoothDevice,mMyHandler );
t.start();
}
//Setting Up a Connecting Client
private class ConnectingThread extends Thread {
OutputStream mmOutputStream;
InputStream mmInputStream;
StringBuilder recDataString = new StringBuilder();
// private final BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
Handler handler;
public ConnectingThread(BluetoothDevice device,Handler mHandler) {
handler = mHandler
BluetoothSocket temp = null;
bluetoothDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
}
public void run() {
// Cancel any discovery as it will slow down the connection
mAdapter.cancelDiscovery();
try {
// This will block until it succeeds in connecting to the device
// through the bluetoothSocket or throws an exception
bluetoothSocket.connect();
Log.e("bluetooth socket",".connect");
mmOutputStream = bluetoothSocket.getOutputStream();
mmInputStream = bluetoothSocket.getInputStream();
//beginListenForData();
Bluetooth_dataDisplay.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Bluetooth_dataDisplay.this, "Connected with Device!", Toast.LENGTH_SHORT).show();
}
});
//change 7
//handler.post(
new Runnable() {
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep looping to listen for received messages
while (true) {
//change 1
try{
Thread.sleep(1000);
}catch(Throwable e){
e.printStackTrace();
}
try {
bytes = mmInputStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
//change 4;
handler.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
//change 6
Log.e("test","6")
//change 2
e.printStackTrace();
break;
}catch(Throwable e1){
//change 5;
Log.e("test","5")
}
}
}.run();
//});
//beginListenForData();
//Log.e("begin", "begindata");
} catch (IOException connectException) {
connectException.printStackTrace();
try {
bluetoothSocket.close();
Log.e("click6", "blueclose");
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
}
,因此它认为递归和放弃了。