Kotlin 1.2 新特性

      網友投稿 664 2025-04-02

      在Kotlin 1.1中,團隊正式發布了JavaScript目標,允許開發者將Kotlin代碼編譯為JS并在瀏覽器中運行。在Kotlin 1.2中,團隊增加了在JVM和JavaScript之間重用代碼的可能性。現在,使用Kotlin編寫的代碼,可以在所有的應用程序中(包括后端,瀏覽器前端和Android移動應用程序)中重復使用。


      想要體驗Kotlin1.2新功能的同學,可以下載官方提供的IntelliJ IDEA 2017.3開發工具,或者升級老的IDE,當然也可以通過在線網站來體驗。

      跨平臺

      跨平臺項目是 Kotlin 1.2 中的一個新的實驗性功能,它允許開發者從相同的代碼庫構建應用程序的多個層——后端、前端和Android應用程序,在這個跨平臺方案中,主要包含三個模塊。

      通用(common)模塊:包含非特定于任何平臺的代碼,以及不附帶依賴于平臺的 API 實現的聲明。

      平臺(platform)模塊:包含用于特定平臺的通用模塊中與平臺相關聲明的實現,以及其他平臺相關代碼。

      常規(regular)模塊:針對特定平臺,可以是平臺模塊的某些依賴,也可以是依賴的平臺模塊。

      要從通用模塊中調用特定于平臺的代碼,可以指定所需的聲明:所有特定于平臺的模塊需要提供實際實現聲明。而在為特定平臺編譯多平臺項目時,會生成通用及特定平臺相關部分的代碼。可以通過 expected 以及 actual 聲明來表達通用代碼對平臺特定部分的依賴關系。expected 聲明指定了一個 API(類、接口、注釋、頂層聲明等)。actual 聲明或是 API 的平臺相關實現,或是在外部庫中 API 現有實現的別名引用。下面是官方提供的相關例子:

      通用模塊

      //?expected?platform-specific?API:expect?fun?hello(world:?String):?Stringfun?greet()?{????//?usage?of?the?expected?API: ????val?greeting?=?hello("multi-platform?world") ????println(greeting) } expect?class?URL(spec:?String)?{????open?fun?getHost():?String????open?fun?getPath():?String }12345678910111213

      JVM 平臺代碼

      actual?fun?hello(world:?String):?String?=????"Hello,?$world,?on?the?JVM?platform!"http://?using?existing?platform-specific?implementation: actual?typealias?URL?=?java.net.URL12345

      想要獲取更多跨平臺相關的信息,可以查看官方資料介紹。

      請注意,目前跨平臺項目只是一個實驗性功能,這意味著該功能已經可以使用,但可能需要在后續版本中更改設計

      編譯性能

      Kotlin 1.2 新特性

      在1.2的開發過程中,團隊花了很多精力來優化編譯系統,據官方提供的資料顯示,與Kotlin 1.1相比,Kotlin帶來了大約25%的性能提升,并且看到了可以進一步改進的巨大潛力,這些改進將在1.2.x更新中發布。

      下圖顯示了使用Kotlin構建兩個大型JetBrains項目的編譯時間差異。

      語法與庫優化

      除了上面介紹的改動之外,Kotlin還在語法層面進行了部分改進,優化的部分有。

      通過注解聲明數組變量

      自Kotlin1.2開始,系統允許通過注解聲明數組參數,從而取代arrayOf函數的數組聲明方式。例如:

      @CacheConfig(cacheNames?=?["books",?"default"]) public?class?BookRepositoryImpl?{ ????//?...}1234

      可見,新的數組參數聲明語法依賴于注解方式。

      關鍵字lateinit

      lateinit 和lazy一樣,是 Kotlin中的兩種不同的延遲初始化技術。在Kotlin1.2版本中,使用lateinit修飾符能夠用于全局變量和局部變量了,也就是說,二者都允許延遲初始化。例如,當lambda表達式在構造一個對象時,允許將延遲初始化屬性作為構造參數傳過去。

      class?Node(val?value:?T,?val?next:?()?->?Node)fun?main(args:?Array)?{????//?A?cycle?of?three?nodes: ????lateinit?var?third:?Node ????val?second?=?Node(2,?next?=?{?third?}) ????val?first?=?Node(1,?next?=?{?second?}) ????third?=?Node(3,?next?=?{?first?}) ????val?nodes?=?generateSequence(first)?{?it.next()?} ????println("Values?in?the?cycle:?${nodes.take(7).joinToString?{?it.value.toString()?}},?...") }123456789101112131415

      運行上面的代碼,輸出結果如下:

      Values?in?the?cycle:?1,?2,?3,?1,?2,?3,?1,?...1

      延遲初始化屬性檢測

      通過訪問屬性的isInitialized字段,現在開發者可以檢查一個延遲初始化屬性是否已經初始化。

      class?Foo?{ ????lateinit?var?lateinitVar:?String ????fun?initializationLogic()?{ ????????println("isInitialized?before?assignment:?"?+?this::lateinitVar.isInitialized) ????????lateinitVar?=?"value" ????????println("isInitialized?after?assignment:?"?+?this::lateinitVar.isInitialized)???? ????} } fun?main(args:?Array)?{ ????Foo().initializationLogic() }1234567891011121314

      運行結果為:

      isInitialized?before?assignment:?falseisInitialized?after?assignment:?true12

      內聯函數默認參數

      自1.2版本開始,Kotlin允許允許給內聯函數的函數參數填寫默認參數了。

      inline?fun??Iterable.strings(transform:?(E)?->?String?=?{?it.toString()?})?=? map?{?transform(it)?}val?defaultStrings?=?listOf(1,?2,?3).strings()val?customStrings?=?listOf(1,?2,?3).strings?{?"($it)"?}? fun?main(args:?Array)?{????println("defaultStrings?=?$defaultStrings") ????println("customStrings?=?$customStrings")123456789

      運行結果為:

      defaultStrings?=?[1,?2,?3]customStrings?=?[(1),?(2),?(3)]12

      變量類型推斷

      大家都知道,Kotlin的類型推斷系統是非常強大的,現在Kotlin編譯器也支持通過強制轉換的信息,來推斷出變量類型了。比如說,如果你在調用一個返回“T”的泛型方法時,并將它的返回值“T”轉換為特定類型如“Foo”,編譯器就會推斷出這個方法調用中的“T”其實是“Foo”類型。

      這個對安卓開發者而言尤其重要,因為自從API26(Android7.0)開始,findViewById變成了泛型方法,然后編譯器也會正確分析該方法的調用返回值。

      val?button?=?findViewById(R.id.button)?as?Button1

      智能轉換

      當一個變量為某個安全表達式(如校驗非空)所賦值時,智能轉換也同樣運用于這個安全調用的接收者。

      fun?countFirst(s:?Any):?Int?{????val?firstChar?=?(s?as??CharSequence)?.firstOrNull()????if?(firstChar?!=?null)????return?s.count?{?it?==?firstChar?}?//?輸入參數s被智能轉換為CharSequence類型 ????val?firstItem?=?(s?as??Iterable<*>)?.firstOrNull()????if?(firstItem?!=?null)????return?s.count?{?it?==?firstItem?}?//?輸入參數s被智能轉換為Iterable<*>類型?? ????return?-1}fun?main(args:?Array)?{????val?string?=?"abacaba" ????val?countInString?=?countFirst(string) ????println("called?on?\"$string\":?$countInString")????val?list?=?listOf(1,?2,?3,?1,?2)????val?countInList?=?countFirst(list) ????println("called?on?$list:?$countInList") }12345678910111213141516171819202122

      運行結果為:

      called?on?"abacaba":?4called?on?[1,?2,?3,?1,?2]:?212

      另外,Lamba表達式同樣支持對局部變量進行智能轉換,前提是該局部變量只在Lamba表達式之前修改過。

      fun?main(args:?Array)?{ ????val?flag?=?args.size?==?0 ????var?x:?String??=?null ????if?(flag)?x?=?"Yahoo!" ????run?{????????if?(x?!=?null)?{ ????????????println(x.length)?//?x?is?smart?cast?to?String ????????} ????} }12345678910111213

      運行結果為:

      6

      foo的簡寫

      為了簡化調用成員的引用,現在可以不用this關鍵字,::foo而不用明確的接收者this::foo。這也使得可調用的引用在你引用外部接收者的成員的lambda中更方便。

      棄用

      Kotlin1.2版本也棄用了很多不合理的東西。

      棄用:枚舉條目中的嵌套類型

      在枚舉條目中,inner class由于初始化邏輯中的問題,定義一個非嵌套的類型已經被棄用了。這會在Kotlin 1.2中引起警告,并將在Kotlin 1.3中出錯。

      棄用:vararg單個命名參數

      為了與注釋中的數組文字保持一致,在命名形式(foo(items = i))中傳遞可變參數的單個項目已被棄用。請使用具有相應數組工廠功能的擴展運算符。

      foo(items?=?*intArrayOf(1))1

      在這種情況下,有一種優化可以消除冗余陣列的創建,從而防止性能下降。單參數形式在Kotlin 1.2中產生警告,并將被放在Kotlin 1.3中。

      棄用:擴展Throwable的泛型內部類

      繼承的泛型類型的內部類Throwable可能會違反類型安全性,因此已被棄用,Kotlin 1.2中有警告,Kotlin 1.3中有錯誤。

      棄用:只讀屬性的后臺字段

      field = …已經廢棄了在自定義獲取器中分配只讀屬性的后臺字段,Kotlin 1.2中有警告,Kotlin 1.3中有錯誤。

      標準庫

      Kotlin標準庫與拆分包

      Kotlin標準庫現在完全兼容Java 9模塊系統,該系統禁止拆分包(多個jar文件在同一個包中聲明類)。為了支持這一點,新的文物kotlin-stdlib-jdk7 和kotlin-stdlib-jdk8介紹,取代舊的kotlin-stdlib-jre7和kotlin-stdlib-jre8。

      為確保與新模塊系統的兼容性,Kotlin做出的另一個更改是將kotlin.reflect從kotlin-reflect庫中移除。如果您正在使用它們,則需要切換到使用kotlin.reflect.full軟件包中的聲明,這是自Kotlin 1.1以來支持的聲明。

      窗口,分塊,zipWithNext

      為新的擴展Iterable,Sequence以及CharSequence覆蓋這些用例如緩沖或批處理(chunked),滑動窗口和計算滑動平均(windowed),和隨后的項目的處理對(zipWithNext)。

      fun?main(args:?Array)?{ ????val?items?=?(1..9).map?{?it?*?it?} ????val?chunkedIntoLists?=?items.chunked(4) ????val?points3d?=?items.chunked(3)?{?(x,?y,?z)?->?Triple(x,?y,?z)?} ????val?windowed?=?items.windowed(4) ????val?slidingAverage?=?items.windowed(4)?{?it.average()?} ????val?pairwiseDifferences?=?items.zipWithNext?{?a,?b?->?b?-?a?} ????println("items:?$items\n") ????println("chunked?into?lists:?$chunkedIntoLists") ????println("3D?points:?$points3d") ????println("windowed?by?4:?$windowed") ????println("sliding?average?by?4:?$slidingAverage") ????println("pairwise?differences:?$pairwiseDifferences") }123456789101112131415161718

      fill, replaceAll, shuffle/shuffled

      為了操縱列表,Kotlin加入了一組擴展函數:fill,replaceAll和shuffle對MutableList,shuffled用于只讀List。

      fun?main(args:?Array)?{ ????val?items?=?(1..5).toMutableList()????items.shuffle() ????println("Shuffled?items:?$items")????items.replaceAll?{?it?*?2?} ????println("Items?doubled:?$items")????items.fill(5) ????println("Items?filled?with?5:?$items") }12345678910111213

      運行結果為:

      Shuffled items: [5, 3, 1, 2, 4]

      Items doubled: [10, 6, 2, 4, 8]

      Items filled with 5: [5, 5, 5, 5, 5]

      數學運算

      為了滿足一些特殊的需求,Kotlin 1.2添加了一些常見的數學運算API。

      常量:PI和E;

      三角函數:cos,sin,tan和它們的反:acos,asin,atan,atan2,

      雙曲:cosh,sinh,tanh和它們的反:acosh,asinh,atanh

      求冪:pow(擴展函數),sqrt,,hypot ;expexpm1

      對數:log,log2,log10,ln,ln1p,

      四舍五入: ceil,floor,truncate,round(半連)的功能;

      roundToInt,roundToLong(半整數)擴展函數;

      符號和絕對值: abs和sign功能; absoluteValue和sign擴展屬性; withSign 擴展功能;max和min兩個價值觀;

      二進制表示: ulp 擴展屬性; nextUp,nextDown,nextTowards擴展函數;toBits,toRawBits,Double.fromBits(這些是在kotlin包)。

      正則表達式可序列化

      現在,Kotlin可以使用Serializable來序列化正則表達式的層次結構。

      JVM

      構造函數調用規范化

      自1.0版以來,Kotlin支持復雜控制流的表達式,例如try-catch表達式和內聯函數調用。但是,如果構造函數調用的參數中存在這樣的表達式時,一些字節碼處理工具不能很好地處理這些代碼。為了緩解這種字節碼處理工具的用戶的這個問題,我們添加了一個命令行選項(-Xnormalize-constructor-calls=MODE),它告訴編譯器為這樣的結構生成更多的類Java字節碼。

      其中,這里的MODE有以下情況:

      disable (默認) - 以和Kotlin 1.0和1.1相同的方式生成字節碼;

      enable - 為構造函數調用生成類似Java的字節碼。這可以改變類加載和初始化的順序;

      preserve-class-initialization -為構造函數調用生成類似Java的字節碼,確保保持類的初始化順序。這可能會影響應用程序的整體性能;只有在多個類之間共享一些復雜的狀態并在類初始化時更新時才使用它。

      Java默認方法調用

      在Kotlin 1.2之前,接口成員在針對JVM 1.6的情況下重寫Java默認方法會在超級調用上產生一個警告:Super calls to Java default methods are deprecated in JVM target 1.6. Recompile with ‘-jvm-target 1.8’。在Kotlin 1.2中,會出現一個錯誤,因此需要使用JVM target 1.8來編譯這些代碼。

      x.equals(null)

      調用x.equals(null)上被映射到Java原始(平臺類型Int!,Boolean!,Short!, ,Long!,Float!,Double!)Char!返回不正確true時x為空。從Kotlin 1.2開始,調用x.equals(…)一個平臺類型的null值會拋出一個NPE (但是x == …不會)。

      要返回到1.2之前的行為,請將該標志傳遞-Xno-exception-on-explicit-equals-for-boxed-null給編譯器。

      內聯擴展空修復

      在以前的版本中,在平臺類型的空值上調用的內聯擴展函數沒有檢查接收器是否為null,并因此允許null轉義到其他代碼中。Kotlin 1.2中強制執行此檢查,如果接收方為空,則拋出異常。

      JavaScript

      TypedArrays支持

      JS類型的數組支持將Kotlin原始數組(例如IntArray,DoubleArray)轉換為JavaScript類型的數組,這以前是可選入功能,默認情況下已啟用。

      除此之外,Kotlin的編譯器現在提供一個將所有警告視為錯誤的選項。使用-Werror命令行,或者修改如下配置:

      compileKotlin?{ ????kotlinOptions.allWarningsAsErrors?=?true}123

      想要了解更多的官方知識介紹,請查看:Kotlin 1.2帶來了什么新特性

      HTTP Java Kotlin

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:我的公式一打開就會顯示無法創建對象請確認對象已經在系統注冊表里注冊
      下一篇:怎樣換皮膚(怎樣換皮膚顏色)
      相關文章
      国产亚洲真人做受在线观看| 亚洲激情中文字幕| 亚洲av午夜成人片精品电影| 精品亚洲成在人线AV无码| 亚洲精品无码午夜福利中文字幕| 亚洲午夜福利精品久久| 日韩欧美亚洲中文乱码| 亚洲综合无码一区二区痴汉| 亚洲国产夜色在线观看| 亚洲欧洲国产综合| 亚洲天天在线日亚洲洲精| 亚洲国产一区二区a毛片| 亚洲成AV人片一区二区| 国产亚洲精品精华液| 亚洲精品无码久久久影院相关影片| 超清首页国产亚洲丝袜| 亚洲精品WWW久久久久久| 亚洲av午夜精品一区二区三区| mm1313亚洲精品国产| 亚洲精品无码av片| 337p日本欧洲亚洲大胆人人| 亚洲GV天堂无码男同在线观看| 亚洲av无码偷拍在线观看| 亚洲avav天堂av在线网毛片| 国产成人精品日本亚洲语音 | 亚洲bt加勒比一区二区| 亚洲精品无码午夜福利中文字幕| 337p日本欧洲亚洲大胆裸体艺术| 亚洲综合无码AV一区二区| 亚洲色欲久久久综合网| 国产亚洲一区二区在线观看| 亚洲精品无码MV在线观看| 亚洲AV美女一区二区三区| 久久精品国产亚洲AV电影| 亚洲大片免费观看| 最新亚洲春色Av无码专区 | 国产亚洲精品拍拍拍拍拍| 亚洲日本乱码在线观看| 久久精品亚洲日本佐佐木明希| 久久亚洲AV成人出白浆无码国产 | 亚洲精品国产高清嫩草影院|