内容简介:Kotlin 跟 findViewById 的类型推导冲突问题
记录一个小坑
1 描述
从 version 26 开始,com.android.support:appcompat-v7 中的 findViewById 方法的返回值从 View 改成了 <t extends View> 。
对于开发者来说,喜大普奔的好处当然是以后终于可以不用在每个 finViewById 方法前面加个丑陋的类型强转了。 但是福兮祸兮,好事的背后也难免会有一些不如意的地方。
比如,如果你在用 Kotlin 的话,项目中可能会有很多类似这样的代码:
// 代码 1 val textView = findViewById(R.id.textView) as TextView
这是 Kotlin 的习惯写法,种写法实际上是跟下面这种写法是等价的
// 代码 2 val textView : TextView = findViewById(R.id.textView) as TextView
由于 Kotlin 的 类型推导 特性,我们可以在声明 textView 变量的时候不必显式说明,系统会自动从后面的赋值语句中推测出它的类型是 TextView 。
但是在 version 26 之后, 代码 1 的这种写法就会报错了:
Type inference failed: Not enough information to infer parameter T in
fun
Please specify it explicitly
意思是没有足够的信息来推断 findViewById 的返回类型。
2 原因
上述错误的本质是 类型推导 的冲突。
如上所说,我们对 textView 的定义并没有说明其类型,它的类型是从后面的赋值语句中推导出来的。
而新版本的 findViewById ,其返回类型是 <t extends View> ,这是一个泛型的声明,具体类型则是根据所赋值的变量类型来确定的。
—— 等号的左右两边互相依赖,互相还都没有指明,可不就冲突报错了么!
3 解决方案:
既然是因为『两个相互依赖的类行推导都没有指明类型』,那解决方案自然就是选其中一个指明类型咯。
3.1
在等号左边声明类型:
// 代码 3 val textView : TextView = findViewById(R.id.textView)
3.2
在等号右边表明类型。
诸如这种带泛型签名的函数也是可以在调用时显式地指明类型的:
// 代码 4 val textView = findViewById<textview>(R.id.textView)
4 总结
-
这只是个很简单的小问题,很好解决,但是了解其本质的过程才是更让人享受的过程~
-
有意思的是:As 默认支持 Kotlin 跟 findViewById 更新这两件事 —— 都是在这次的 IO 大会上宣布的。而且现在(2017.06.05)用 AS 新建一个项目并开启 Kotlin 支持,然后把 support-v7 包升级到 26,就会发现默认的页面就会报这个错 :see_no_evil:…… 希望 Google 能早日改正~
关于作者 :
http://www.barryzhang.com
https://github.com/barryhappy
http://www.jianshu.com/users/e4607fd59d0d
以上所述就是小编给大家介绍的《Kotlin 跟 findViewById 的类型推导冲突问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Mastering Regular Expressions, Second Edition
Jeffrey E F Friedl / O'Reilly Media / 2002-07-15 / USD 39.95
Regular expressions are an extremely powerful tool for manipulating text and data. They have spread like wildfire in recent years, now offered as standard features in Perl, Java, VB.NET and C# (and an......一起来看看 《Mastering Regular Expressions, Second Edition》 这本书的介绍吧!