在熟练使用java中,通过TCP连接 会写出以下两种方式也可能有不同的方式.,我一般用这两种 第一种
while (true) {
try {
if (null != is && devConnect) {
int readLen = is.read(readBuffer);
if (readLen > 0) {
for (int i = 0; i < readLen && i < readBuffer.length; i++) {
recvFromDevData.offer(readBuffer[i]);
}
} else {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
devConnect = false;
devDisConnect();
}
}
第二种 或者直接通过while来进行判断处理字节
private void readTCPData() {
try {
byte[] bytes = new byte[1024];
int len = 0;
if (in != null) {
while ((len = in.read(bytes)) != -1) {
for (int i = 0; i < len; i++) {
queueData.offer(bytes[i]);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
但是在kotlin中,如果按照第二种写法去写,while循环里的(len = in.read(bytes)) != -1是会报错的 提示的很清楚,赋值不是表达式,在此上下文中只允许表达式 根据提示我们要把里面修改成为表达式形式
try {
val b = ByteArray(2048)
var length = 0
while (socketIn?.read(b)!!.also { length = it } != -1) {
val tempByte = ByteArray(length)
tempByte.forEachIndexed { index, _ ->
receiveQueue.offer(b[index])
}
}
} catch (e: IOException) {
connect = false
e.printStackTrace()
}
这里的while中就是一个表达式形式,当然你直接读取字节在去判断也是可以的
while (socketIn?.read(b)!! != -1)
但是你需要用到length的字节长度,所以通过also来对length进行赋值.,因为also函数内是会返回自己参数的一个扩展函数.并且函数中包括自身的值 以下为also的源码
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
或者使用apply来使用
try {
val b = ByteArray(2048)
var length = 0
while (socketIn?.read(b)!!.apply { length = this } != -1) {
val tempByte = ByteArray(length)
tempByte.forEachIndexed { index, _ ->
receiveQueue.offer(b[index])
}
}
} catch (e: IOException) {
connect = false
e.printStackTrace()
}
对比下这两个的源码
public inline fun <T> T.apply(block: T.() -> Unit): T
public inline fun <T> T.also(block: (T) -> Unit): T
apply的参数是函数类型,这个函数类型是一个某类型(T)的扩展函数.返回值一个空 also的参数也是函数类型.这个函数类型的参数是某类型(T)为参数的函数,返回值为空 所以这两种方法都可以给length赋值,只不过调用的方式不一样
socketIn?.read(b)!!.apply { length = this }
socketIn?.read(b)!!.also { length = it }
apply 也就是说socketIn?.read(b)!! 他的类型是Int ,等于 Int.apply{ }这就和你写扩展函数一样的道理了,在内部只能用this去调用当前该类型的值 also socketIn?.read(b)!! 同样是Int类型,只不过他的出现方式是在参数中,而lambda简写中讲到,如果一个lambda只有一个参数,如果不给他重写名字,默认是it.
|