kotlin compilerpcie rc ep 模式区别ab 什么区别

Kotlin 1.0 RC发布,基于JVM的编程语言
查看: 286|
评论: 0|原作者: oschina|来自: oschina
摘要: Kotlin 1.0 RC 发布,更新如下:Languagenew @delegate: use-site target for annotation (e.g. @delegate:Transient)private top-level Kotlin classes should be compiled to package private java classesunfinis ...
Kotlin 1.0 RC 发布,更新如下:Languagenew @delegate: use-site target for annotation (e.g. @delegate:Transient)private top-level Kotlin classes should be compiled to package private java classesunfinished multiline comment is an errorpreviously deprecated language constructs are now errorstype ckecking for use-site variance fixedgeneric functions are compared for specificity through solving a constraint systemhaving multiple vararg parameters for one function is prohibitedsuper-calls to functions with default parameters are prohibited (pass all arguments explicitly)implicit receiver behavior fixedas-import removes original names if they were imported beforeuser code is not allowed in kotlin.** packagestype parameters of extension properties allowed to be indirectly used by the receiver typemembers of private classes can-not be accessed from non-private inline functionsJava interopforEach from Kotlin's library is preferred to forEach from java.lang.Iterablesynthesized declarations (like JavaBeans properties and SAM-converted methods) are now resolved on par with memberssupport added for Java setters that return valuespreviously depreacted Java declarations removed from generated codeprivate setters allowed for lateinit propertieswildcards are not generated for redundant type projections (use List&@JvmWildcard Foo& instead of List&out Foo&)@Nullable/@NotNull annotations from different standard Java packages recognized (javax.annotations, Guava, Android, etc)Standard Librarydiagnostics for multiple conflicting Kotlin runtime versions in classpathsome functions have been made inlinemany inline functions (most of them one-liners) can no longer be
called from Java code. This will help us reduce the size of the runtime
library in the future.library code rearranged into more granular packages (no source changes should be required)associate and associateBy are added to aid construction of maps
associate and associateBy (instead of toMap/toMapBy)groupBy with key- and value-selector functionsMap.getOrElse() and Map.getOrPut() now treat keys associated with null values as missing.Map.getOrImplicitDefault() has been made internalmutableListOf, mutableSetOf, mutableMapOf added to construct mutable collections. linkedListOf is deprecatedtoMutableList added instead of toArrayList. The latter is deprecatedkotlin.system.exitProcess instead of System.exitFile.deleteRecursively only returns false in case of incomplete deletionFile.copyRecursively allows overwriting by specifying argument overwrite=truechanged File.copyTo behavior to be like Files.copy from JDK8.more specific return type for File.inputStream, File.outputStream, String.byteInputStream.IO utility functions taking charset name as a string are deprecated, use ones with Charset parameter.File.useLines and Reader.readLines are introducedFile.(buffered)reader/writer now return less specific InputStreamReader/OutputStreamWriter and use UTF-8 encoding by defaultSequence and Iterable SAM constructor-like functionsComparator- and comparison-related functions are moved to <parisons package (not imported by default)new properties in MatchResult: groupValues and destructured — provided for easier handling of regular expression match resultsLazy is now an interface open for implementationkotlin.system.measureTimeNano renamed to measureNanoTime.plusElement and minusElement functions as a synonyms for list + element and list - element.kotlin.test.assertFailsWith with Class&T& parameter is deprecated, use an overload with KClass&T&.toLinkedMap is deprecated.UTF_32 charset properties added to ChatsetsToolsTo enable Android Extensions, use: apply plugin: 'kotlin-android-extensions'IDEIntention to replace iteration over map entries with a loop using a destructuring declarationInspection and quickfix to cleanup redundant visibility modifiersInspection to replace 'assert' calls checking that a variable is not null with !! or ?: error(...)Show "Kotlin not configured" notification when opening a .kt file in
the IDE if the Kotlin runtime is not configured for the corresponding
moduleAction to generate the toString() methodSupport for implementing members by primary constructor parametersParameter info popup works for showing type parametersCompletion offers name variants based on unresolved identifiers in current fileQuickfix for adding missing branches to a when expressionSupport for moving nested classes to the upper level or into another top-level class@Suppress now works for IDE inspections详情请看:下载:Kotlin 是一个基于 JVM 的新的编程语言,由
开发。其主要设计目标:创建一种兼容Java的语言让它比Java更安全,能够静态检测常见的陷阱。如:引用空指针让
它比Java更简洁,通过支持variable type inference,higher-order functions
(closures),extension functions,mixins and first-class delegation等实现。让它比最成熟的竞争对手语言更加简单。
上一篇:下一篇:
快毕业了,没工作经验,
找份工作好难啊?
赶紧去人才芯片公司磨练吧!!Why Kotlin Sucks - 推酷
Why Kotlin Sucks
This article is based on
in the form of half a joke. In the mentioned article, most of the “problems” are either synthetic and rarely used, or far-fetched due to expectations of the language correspondence to a theoretical paradigm the language should correspond to. On the other hand, the article misses a few things that really complicate my life as an engineer.
I’m not claiming to have an absolute knowledge of
, so there can be some mistakes in the article. I’ll be grateful if you let me know in comments about solutions to the problems I face.
, the most powerful statement has been turned into a useless thing implemented by
inline fun &T& For(it : Iterator&T&, cb : (T) -& Unit) {
while (it.hasNext()) cb(it.next())
fun main(a : Array&String&) {
val list = listOf(1, 3, 4, 12)
println(&for&);
for (it in list) println(it)
println(&FOR&);
For(list.iterator()) { println(it) }
val arr = arrayOf(1, 3, 4, 12)
println(&a-for&); for (it in arr) println(it)
println(&a-FOR&); For(arr.iterator()) { println(it) }
println(&r-for&); for (it in 0..10) println(it)
println(&r-FOR&); For((0..10).iterator()) { println(it) }
As you can see in the example above, even such a primitive implementation of
does not simply work the same way as
, but in all cases, except for working with an array, is absolutely identical to it in the generated code. Writing a few more strings, we can get to a state in which the self-made analogue will require less code than the original one.
Question: Why did they even introduce this keyword to the language and implement a pathetic parody of a special use case of a loop? There already is a pathetic loop.
Actually, I wouldn’t care about
if there was an alternative. But there isn’t one. Unfortunately, life doesn’t end with iterators, and when we need to write some complex loops, we really suffer from the miserable
Histerically-Useless War with nullable
Maybe it’s because I’m old or maybe because during the last 25 five years I’ve successfully written in С that has (sic!) such thing as
, I don’t feel euphoria from repeating the trivial “shoot in the foot” or “a million-dollar error”. As a result, I simply don’t understand what they’re fighting about. I don’t get the difference between the program is being crashed during the arguments check versus when the arguments are used.
What’s the point of declaring
null-safety
if it can’t provide it even theoretically? The value of
is in the language itself, it’s also in Java, without the infrastructure of which Kotlin is frankly of no interest. How can we protect ourselves from something that is beyond the language and is not controlled by it? There’s no way to do it. It’s not more than a fashionable trend, uglified sources and endless problems.
However, I’m far from being the kind of person who tells other people how they should live. I would ignore the frenzy about
if it wasn’t for the constant problems with it. Or rather the abstraction, with which
complicates my life.
var value : Int? = null
fun F() : Int {
if ( value != null ) return 0
return value // error
Smart cast to ‘Int’ is impossible, because ‘value’ is a mutable property that could have been changed by this time
error is driving me nuts. I want to kill someone or break something.
Where, how and by what can this property be modified between these two strings??!!! By a neighboring thread? Where does this absolutely crazy confidence of a compiler that each character of my program is an element of multithread concurrency come from? Even in case of writing complex multithread code, thread intersections occur on a very small size of the source code, but due to compiler’s repressive care about this feature, I have problems all along.
Who came up with the idea of two exclamation points? Idiots! Two aren’t enough to make me crazy. You’d better come up with five. Or ten. On both sides. So that we could easily understand where the most not kosher and “unsafe” code is.
var value : Int? = null
fun F() : Int {
if (value == null) return 0
return when (Random().nextInt()) {
-& value!! + 2
-& value!! + 1
-& value!! * 4
The worst thing is that our life does not fit the perfect concept of “safe” code of those who need to sell a book about new tendencies every year. Unfortunately,
is a normal “unknown” state of a set of objects. But when working with them, we have to write some completely unnecessary things.
The funniest thing about
is that all of this does not work. I’ve almost resigned myself with writing useless things in my code hoping that one day this “will save me”.
Yeah, right.
public class jHelper {
public static jHelper jF() { }
public void M() {}
val a = jHelper.jF()
It compiles fine without any errors or warnings, but then crashes with the standard
NullPointerException
during the runtime, since Kotlin does not check anything, anywhere. But where’s the promised, or rather
, safety?!
Anyway, I’d like to say the following: * Constant headache with solving far-fetched problems
in my code
; * Constant headache about
when working with
in my code
; * Constant overhead generated by the compiler when checking all function parameters and when setting any values
in my code
; * Zero safety for any data coming
from the outside
So, the headache is in the part I know and can control. As for external things, everything will silently fall to pieces at the first opportunity. Cool, right?
Why Assignment is not an Expression?
Being pathetic
is still an expression, but assignment has been deprived of this feature. Why can’t I write like this?
var value = 10
fun F() : Int {
return value = 0 // Error
Or like that:
var v1 = 1
var v2 = 1
var v3 = 1
v1 = v2 = v3 = 0 // Error
What’s so criminal about this code? Let me guess… You’re protecting the user from
? Quite unlikely as this simply won’t work without the automatic type casting that isn’t available in
. Okay, I give up. Who knows the answer?
What’s Bad About ?: Operator?
Why was the
operator amputated? What was so terrible they saw in the structure like this:
value != 0 ? &Y& : &N&
Everything’s great with
if (value != 0) &Y& else &N&
except for complete alternativeness (where else is it available?) and the fact that usually writing
if () else
takes more space than the expression itself.
Why Was Automatic Type Casting Killed?
Yes, a complete type casting to each other is a pure evil. I’m absolutely against making puzzles that mutual number and string conversion leads to. Actually, I’m even for distinguishing integers and floating point numbers. But why did they cut all of it? Why couldn’t they use standard and generally accepted rules of typecasting that exist in the vast majority of languages?
Okay, whatever, they did cut it. Hello Pascal. But why do the lie in documentation that
? Why say “there are no” if I can easily make it?
val i = 10
val l = 12L
val f = 12.1
val l1 = i+100/l-f
Where’s the expected hardcore?
val l1 = i.toDouble() + 100.toDouble() / l.toDouble() – f
That is, there’s no automatic typecasting… although… it’s as if there… but only for expressions… and also for constants. But if we need to pass a variable as a parameter or assign a variable without calculations — there’re lots of things to deal with. As it’s so important, and we focus all attention on the fact that we obtain
, and exactly
I almost feel how a number of errors is melted away thanks to such care.
I also wanted to mention the highly desirable:
val c : SomeClass? = null
if ( c ) &not-null&
if ( !c ) &is-null&
but I won’t as I fear for my life.
type aliases
People have been asking to add aliases to
for a long time. They did. I don’t know in what situations people are planning to use this but, in my opinion, there’s no sense in such implementations. They’d better call this structure a macro — and I would have nothing against it.
Let’s see when we need aliases in a language. I would suggest the following use-cases:
Creating an alternative name for an existing class. The task is quite useless but maybe someone will need it. The existing aliases fully cope with this task.
Creating a new type without creating a new class. The existing aliases cannot solve this task as they are not an independent type. It’s impossible to distinguish two aliases that differ in name only.
Less writing when using template types. This task is the most useful and frequently used. The existing aliases can solve only its descriptive part (see point 1). That is, we can use them to describe a type of variables, parameters, the returned value, and create an object of such a (base) type. We cannot use an alias for a template type for typecasting or checking the object type.
In practice, we have the following:
typealias aI = SuperPuperClassA
typealias pSI = Pair&String,Int&
typealias pIS = Pair&Int,String&
typealias pOTHER = Pair&String,Int&
typealias aS = List&String&
class SuperPuperClassA {
fun F() = pSI(&&,10)
fun main(a : Array&String&) {
val a = aI()
val i1 = a.F()
val i2 : Pair&*,*& = a.F()
val i3 : Any = a.F()
//This code compiles, and the condition is met
if ( i1 is pSI ) println(&ok&)
if ( i1 is pOTHER ) println(&ok&)
//This code does NOT compile
if ( i1 is pIS ) println(&not compile&)
if ( i2 is pSI ) println(&not compile&)
if ( i2 is pIS ) println(&not compile&)
if ( i3 is pSI ) println(&not compile&)
if ( i3 is pIS ) println(&not compile&)
Note that the condition will be met in both strings where code compiles. We cannot distinguish them as alias is not a full-fledged type. Actually,
could distinguish them at least in cases similar to this example (the entire code with obvious and well-known types), but seems like there’s no wish to do it.
Code that does not compile has the same problem: “Cannot check for instance of erased type”. The problem is in poor (or lack of) templates in the JVM runtime.
Summarizing It All
Aliases in the current implementation are text macros that simply replace one text with another one. Trying to make them show some intellectual behavior can lead to disappointments or errors.
Oh, did I mention that we can describe only global aliases, beyond any class?
Nested and local type aliases are not supported.
As a result, they’re also inconvenient to be used like macros, to reduce writing within one class, as even with the
modifier they’re visible within the entire project.
Poor Generics
Generics in
in general and in
in particular are miserable due to the same reason: JVM knows nothing about generics and all these angle brackets in the language are no more than syntactic sugar.
I don’t care about Java problems. I’m concerned about poor generics in
that is positioned as a different language, not as a Java’s preprocessor. So it’s useless to point at
drawbacks.
I can somehow live with the fact that we cannot (it’s useless) use template types for checking a type or casting it, as the compiler will spit out an error about it, but that’s not all.
Here’s another puzzle:
/*00*/ class C&T&(val value : Any) {
fun F() : T {
val v = value as T //Warning of the Compiler &Unchecked cast: Any to T&
} catch(ex : RuntimeException) {
println(&Incompatible&)
// Hack to Illustrate that the exception will be eaten and won’t go further
return 0 as T
/*13*/ fun fTest() {
val a = C&Int&( 12.789 )
println( &rc: ${a.F()}& )
val b = C&Int&( &12.123& )
println( &rc: ${b.F()}& )
Here, in the C class, we try to check whether the object type is compatible with the template type.
The Question: How will this code compile?
Possible answers: 1. It won’ 2. It will compile and display “12”, “12”; 3. It will compile, execute, and display “12”, “Incompatible”; 4. It will compile, execute, and display “12.789”, “12.123”; 5. It will crash inside the
function (on which line?) 6. It will crash insde the
function (on which line?)
The correct answer is 6. It will crash insde the
function on line 18.
Exception in thread &main& java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
at jm.test.ktest.KMainKt.fT(kMain.kt:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
The next task: who can explain why? 1. Why didn’t it crash during the first call, where
is passed instead of
? 2. Why the
block was not performed? 3. How a casting error with
types could even reach the code that uses the
Let’s review it. I’ll tell you in short. Draw your own conclusions. Here’s code Kotlin generates to check the type inside of
// val v = value as T
GETFIELD jm/test/ktest/C.value : Ljava/lang/O
CHECKCAST java/lang/Object
If we think really hard (or know beforehand that it’s inefficient), it is possible to explain the
CHECKCAST Object
. It’s more difficult to explain why we generate this code at all, as it’s completely useless, but it’s a question to a different part of the compiler.
Here’s code that is generated when we call
LINENUMBER 18 L6
INVOKEVIRTUAL jm/test/ktest/C.F ()Ljava/lang/O
CHECKCAST java/lang/Number
And again, if we think really hard (or know beforehand), it is possible to explain the existence of correct types in this place. But for me personally, the mere fact of type checking
the function call was a big surprise. Oh yea, turns out, for
, Kotlin generates an
type checking every time the generic result is used.
Despite the many syntactic charms of
generics, they can play a dirty trick with us.
I understand that there’re no generics in
. I wouldn’t mention this if it was impossible to organize proper work with generics anywhere. But here’s a vivid example —
Company managed to add to С and Pascal such a powerful
that it has no alternatives. But it’s not machine code, it’s
, and it seems possible to provide a fully functional use of generics in the
code in it. But it’s not available. As a result, the result is different, but the situation is even worse than in Java due to the diversity of syntactic options.
Let’s create generics with a Java puzzle.
public class jTest&T& {
jTest( Object v ) { value = }
public T F() { return (T) } //Compiler warning &Unchecked cast&
public static void Test() {
jTest&Integer& a = new jTest&Integer&( 12.123 );
System.out.print( &rcA: & );
System.out.print( a.F() );
jTest&Integer& b = new jTest&Integer&( &12.789& );
System.out.print( &\nrcB: & );
System.out.print( b.F() );
System.out.print( &\n& );
And try to call it from
fun fTJ_1() {
val a = jTest&Int&( 12.123 )
println( &rc: ${a.F()}& )
val b = jTest&Int&( &12.789& )
println( &rc: ${b.F()}& )
fun fTJ_2() {
jTest.Test()
I’m not going to bore you with various puzzles for all possible variants and will simply reduce it to a simple task: How will behave a program, in which: 1. Both the generic and its usage is implemented in
; 2. The generic is in Java but it’s used is in
; 3. Both the generic and implementation are in
; What will be the results of the program execution in each case?
Possible answers:
All examples will have the same results.
All examples will have different results.
All examples with the implementation in
will have the same results, and all examples with Java will have different results.
The correct answer – all three variants will behave differently.
Exception in thread &main& java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
Kotlin-&Java
Exception in thread &main& java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
rcA: 12.123
rcB: 12.789
Why is it so and not otherwise? It’s going to be your homework.
No Syntax to Describe Structures
If we take
absolutely any
comparable language (even Java or Scala, or Groovy and lots of other ones, starting from Lua to even С++), they have everything to simplify the life when creating data structures.
is the only language I know without any syntax to describe data structures. There’re only three functions:
In case with arrays and lists, the syntax is quite complex but looks structured:
val iArr1 = arrayOf(1, 2, 3)
val iArr2 = arrayOf( arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3) )
val iArr3 = arrayOf(
arrayOf(arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3)),
arrayOf(arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3)),
arrayOf(arrayOf(1, 2, 3), arrayOf(1, 2, 3), arrayOf(1, 2, 3))
But it’s much worse with maps:
val tree = mapOf(
Pair(&dir1&, mapOf(Pair(&file1&, 0), Pair(&file2&, 1))),
Pair(&dir2&, mapOf(
Pair(&dir21&, mapOf(Pair(&file1&, 0), Pair(&file2&, 1))),
Pair(&dir22&, mapOf(Pair(&file1&, 0), Pair(&file2&, 1))))) )
I don’t know how other people describe constant data but I feel great discomfort when trying to use something more complex than a one-dimensional list.
We can obviously convert the data to any convenient format (JSON and read it from here), but…
It is somehow redundant to place each dozen of strings into a separate file just to have an ability to manipulate them. But that’s exactly what we have to do.
Our efforts on writing the code structure directly in a program and in an external file, with further reading them, are simply incomparable.
In case of changing the data structure, besides code, we also need to fix tons of completely unnecessary text responsible for loading that code.
Anyway, the concept of minimalism is cool but extremely inconvenient.
P.S. If anyone wants a nail in the head, write a library to work with matrices. You will learn to distinguish
Array&Array&Array&Array&Double&&&&
Array&Array&Array&Double&&&
at the first glance and from any distance.
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 kotlin compiler 的文章

 

随机推荐