RPA 實戰:讓小姐姐填滿你的硬盤(上)
1350
2025-03-31
簡述:
今天我們來講點Kotlin中比較時髦的東西,有的人可能會說:“不像你之前的風格啊,之前的文章不是一直在死扣語法以及語法糖背后秘密。當你還在死扣泛型語法的時候,別人的文章早就說了Kotlin/Native和Kotlin1.3的新特性”。瞬間感覺自己out了,今天我們就說說這些時髦的東西,也許你能看到一些和別人不一樣的東西哦。因為看到有Kotlin中文社區兩位大佬(這兩位大佬是我一年多以前開始寫Kotlin的時候就關注了他們)的演講日程以及JetBrains資深布道師Hali的演講,沒有過多思考直接買票.
總結了一下結合自己實際的開發,給大家帶來以下幾篇文章。
1、Kotlin/Native1.0 Beta(嘗鮮篇)
簡述:
今天我們來講點Kotlin中比較時髦的東西,有的人可能會說:“不像你之前的風格啊,之前的文章不是一直在死扣語法以及語法糖背后秘密。當你還在死扣泛型語法的時候,別人的文章早就說了Kotlin/Native和Kotlin1.3的新特性”。瞬間感覺自己out了,今天我們就說說這些時髦的東西,也許你能看到一些和別人不一樣的東西哦。因為看到有Kotlin中文社區兩位大佬(這兩位大佬是我一年多以前開始寫Kotlin的時候就關注了他們)的演講日程以及JetBrains資深布道師Hali的演講,沒有過多思考直接買票.
總結了一下結合自己實際的開發,給大家帶來以下幾篇文章。
1、Kotlin/Native1.0 Beta(嘗鮮篇)
2、Kotlin中1.3版本新特性都有哪些?
3、Kotlin中的Coroutine(協程)在Android上應用(協程學前班篇)
4、Ktor異步框架初體驗(Ktor學前班篇)
那么,今天就開始第一篇,看過一些大佬寫關于Kotlin/ Native的文章,基本上都是翻譯了Kotlin Blog的官網博客, 具體如何實踐的還是比較少的。今天我不打算這么講,既然今天的主題是時髦那就講點有意思的東西。一起來看下今天提綱:
一、重新認識Kotlin語言
在開始之前,我覺得有必要一起重新來認識一下Kotlin這門語言,很多人一直都認為它不就是門JVM語言和Java、Scala一樣都是跑在JVM虛擬機上。其實Kotlin并不僅僅是一門JVM語言,它的野心是真的大,JVM語言已經無法滿足它的雄心壯志了。它是一門多平臺的靜態編譯型語言,它可以用于JVM上(只不過在JVM層面比較出名而已,導致很多人都認為它是門JVM語言),實則它可以編譯成JavaScipt運行在瀏覽器中也可以編譯成IOS的可運行文件跑在LLVM上
二、Kotlin/Native的基本介紹
用官方的話來說Kotlin / Native是一種將Kotlin代碼編譯為本機二進制文件的技術,可以在沒有虛擬機的情況下運行。它是基于LLVM的后端,用于Kotlin編譯器和Kotlin標準庫的本機實現。
Kotlin/Native目前支持以下平臺:
--- iOS (arm32, arm64, emulator x86_64)
--- MacOS (x86_64)
--- Android (arm32, arm64)
--- Windows (mingw x86_64)
--- Linux (x86_64, arm32, MIPS, MIPS little endian)
--- WebAssembly (wasm32)
為了更好說明Kotlin/Native能力,下面給出張官方的Kotlin/Native能力圖:
對于Kotlin/Native之前一直沒有去玩過,只是經常聽到社區小伙伴們說編譯起來巨慢,感覺好時髦啊。抱著好奇心,并且也符合我們這篇文章時髦的主題,決定一步步帶大家玩一玩。
三、Kotlin/Native開發IOS HelloWorld
AppCode 2018.1(建議下載最新版本,這里不是最新版本不過也能玩哈,最新版本應該到了2018.3)
Kotlin/Native Plugin 181.5087.34(注意: 插件和AppCode IDE的版本匹配問題,建議把IDE安裝好,然后IDE搜索下載會默認給最佳匹配的插件版本的)
Xcode 9.2(注意: 這里Xcode版本需要AppCode版本匹配,否則會有問題的,不過不匹配的話IDE會有提示的,建議如果AppCode 2018.1(Xcode 9.2), AppCode 2018.3(Xcode 10.0))
第一步: 選擇左側的Kotlin/Native, 并選擇右側的Sing View App with a Kotlin/Native Framework
第二步: 填寫項目名和包名,選擇語言Swift(這里先以Swift為例)
第三步: 最后finish即可創建完畢Kotlin/Native項目,創建完畢后項目結構如下
如果你比較幸運跑起來的話,效果應該是在模擬器裝一個APP并且起了一個空白頁,終端上輸出了"Hello from Kotlin!"的Log,類似這樣:
注意: 但是你是真題測試,而且Run頂部默認只有一個IOS Device選項的話,然后你又點了Run 說明而且會報如下錯誤
這個問題是因為默認IOS Device選項是表示用真機調試哈,然后這邊就需要一個IOS開發者賬號。設置開發者賬號的話,建議使用Xcode去打開該項目然后給該項目配置一個開發者賬號。
設置完畢Xcode后,AppCode會自動檢測到刷新的。
四、Kotlin/Native開發IOS 運行原理分析
看到上面IOS HelloWorld項目運行起來,大家有沒有思考一個問題,Kotlin的代碼的代碼是怎么在IOS設備上跑起來呢?
實際上,在這背后使用了一些腳本和工具在默默支撐著整個項目的運行,如前所述,Kotlin / Native平臺有自己的編譯器,但每次想要構建項目時手動運行它明顯不是高效的。 所以Kotlin團隊了選擇Gradle。Kotlin / Native使用Gradle構建工具在Xcode中自動完成Kotlin / Native的整個構建過程。在這里使用Gradle意味著開發人員可以利用其內部增量構建架構,只需構建和下載所需內容,從而節省開發人員的寶貴時間。
如果,你還對上述有點疑問不妨一起來研究下Kotlin/Native項目中的構建參數腳本:
打開構建腳本是需要在Xcode中打開的,具體可以參考如下圖:
通過以上項目可以分析到在Xcode中編譯一個Kotlin/Native項目,實際上在執行一段shell腳本,并在shell腳本執行中gradlew命令來對Kotlin/Native編譯,該腳本調用gradlew工具,該工具是Gradle Build System的一部分,并傳遞構建環境和調試選項。 然后調用一個konan gradle插件實現項目編譯并輸出xxx.kexe文件,最后并把它復制到iOS項目構建目錄("$TARGET_BUILD_DIR/$EXECUTABLE_PATH")。
最后來看下Supporting Files中的build.gradle構建文件,里面就引入了konan插件(Kotlin/Native編譯插件), 有空的話建議可以深入研究下konan插件,這里其實也是比較淺顯分析了下整個編譯過程,如果深入研究konan插件源碼的話,更能透過現象看到Kotlin/Native本質,這點才是最重要的。
buildscript?{
ext.kotlin_version?=?'1.2.0'
repositories?{
mavenCentral()
maven?{
url?"https://dl.bintray.com/jetbrains/kotlin-native-dependencies"
}
}
dependencies?{
classpath?"org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.7"
classpath?"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply?plugin:?'kotlin'
repositories?{
mavenCentral()
}
dependencies?{
compile?"org.jetbrains.kotlin:kotlin-stdlib"
}
apply?plugin:?'konan'
konan.targets?=?[
'ios_arm64',?'ios_x64'
]
konanArtifacts?{
program('KotlinNativeOC')
}
五、Kotlin/Native項目結構分析
我們知道main函數是很多應用程序的入口,ios也不例外,在AppDelegate.swift中有@UIApplicationMain的注解,這里就是APP啟動的入口。
@UIApplicationMain?//main函數注解入口,所以AppDelegate類相當于啟動入口類
class?AppDelegate:?UIResponder,?UIApplicationDelegate?{
var?window:?UIWindow?//默認加了UIWindow
func?application(_?application:?UIApplication,?didFinishLaunchingWithOptions?launchOptions:?[UIApplicationLaunchOptionsKey:?Any]?)?->?Bool?{
//?KNFKotlinNativeFramework?class?is?located?in?the?framework?that?is?generated?during?build.
//?If?it?is?not?resolved,?try?building?for?the?device?(not?simulator)?and?reopening?the?project
NSLog("%@",?KNFKotlinNativeFramework().helloFromKotlin())//注意:?這里就是調用了Kotlin中的一個helloFromKotlin方法,并把返回值用Log打印出來,所以你會看到App啟動的時候是有一段Log被打印出來
return?true
}
...
}
KotlinNativeFramework類
class?KotlinNativeFramework?{
fun?helloFromKotlin()?=?"Hello?from?Kotlin!"?//返回一個Hello?from?Kotlin!字符串
}
但是呢,有追求的程序員絕對不能允許跑出來的是一個空白頁面,空白頁面那還怎么裝逼呢? 哈哈。在ViewController.swift中的viewDidLoad函數中加入一個文本(UILabel)。
class?ViewController:?UIViewController?{
override?func?viewDidLoad()?{
super.viewDidLoad()
let?label?=?UILabel(frame:?CGRect(x:?0,?y:?0,?width:?300,?height:?21))
label.center?=?CGPoint(x:?160,?y:?285)
label.textAlignment?=?.center
label.font?=?label.font.withSize(15)
label.text?=?"Hello?IOS,?I'm?from?Kotlin/Native"
view.addSubview(label)
}
override?func?didReceiveMemoryWarning()?{
super.didReceiveMemoryWarning()
//?Dispose?of?any?resources?that?can?be?recreated.
}
}
最后重新run一遍,效果如下:
在IOS同事幫助下,進一步了解IOS APP啟動基本知識,這將有助于我們接下來改造我們項目結構,使得它更加簡單,完全可以刪除額外的Swift代碼,包括APP啟動代理那塊都交由Kotlin來完成。
第一步: 先創建一個Kotlin/Native + OC 的項目,這里就不重復創建過程,直接把OC目錄結構給出:
第二步: 可以看到OC與Swift項目結構差不多哈,可以看到其中有幾個重要的文件,main.m、AppDelegate.m、ViewController.m
main.m APP啟動入口,相當于main函數,先從main函數入手,然后一步步弄清整個啟動流程。
#import?
#import?"AppDelegate.h"
int?main(int?argc,?char?*?argv[])?{
@autoreleasepool?{
return?UIApplicationMain(argc,?argv,?nil,?NSStringFromClass([AppDelegate?class]));//這里也調用了AppDelegate類
}
}
第三步: 然后轉到AppDelegate.m,可以看到在didFinishLaunchingWithOptions函數中調用了KNFKotlinNativeFramework中的helloFromKotlin函數。
-?(BOOL)application:(UIApplication?*)application?didFinishLaunchingWithOptions:(NSDictionary?*)launchOptions?{
//?KNFKotlinNativeFramework?class?is?located?in?the?framework?that?is?generated?during?build.
//?If?it?is?not?resolved,?try?building?for?the?device?(not?simulator)?and?reopening?the?project
NSLog(@"%@",?[[[KNFKotlinNativeFramework?alloc]?init]?helloFromKotlin]);//注意這里調用helloFromKotlin,并輸出日志
return?YES;
}
到這里很多人就會問了,看你上面說了那么并沒有看到你Kotlin在做什么事,全是Swift和OC在做APP啟動。現在就是告訴你Kotlin如何去替代它們做APP啟動的事了。
先新創建一個項目,這次創建的不再是Sing View App with a Kotlin/Native Framework, 而是一個Application項目。
生成后的目錄文件全是Kotlin文件,具體如下:
生成的main.kt替代main.m,并設置對應啟動的AppDelegate
import?kotlinx.cinterop.autoreleasepool
import?kotlinx.cinterop.cstr
import?kotlinx.cinterop.memScoped
import?kotlinx.cinterop.toCValues
import?platform.Foundation.NSStringFromClass
import?platform.UIKit.UIApplicationMain
fun?main(args:?Array
memScoped?{
val?argc?=?args.size?+?1
val?argv?=?(arrayOf("konan")?+?args).map?{?it.cstr.getPointer(memScope)?}.toCValues()
autoreleasepool?{
UIApplicationMain(argc,?argv,?null,?NSStringFromClass(AppDelegate))//注意:?在這里設置對應啟動的AppDelegate
}
}
}
生成AppDelegate替代原來的AppDelegate.m,并且在內部設置好啟動的Window.
import?kotlinx.cinterop.initBy
import?platform.Foundation.NSLog
import?platform.UIKit.*
class?AppDelegate?:?UIResponder(),?UIApplicationDelegateProtocol?{
override?fun?init()?=?initBy(AppDelegate())
private?var?_window:?UIWindow??=?null
override?fun?window()?=?_window
override?fun?setWindow(window:?UIWindow?)?{?_window?=?window?}
override?fun?application(application:?UIApplication,?didFinishLaunchingWithOptions:?Map
NSLog("this?is?launch?from?kotlin?appDelegate")
return?true
}
companion?object?:?UIResponderMeta(),?UIApplicationDelegateProtocolMeta//注意:一定得有個companion?object否則在main函數NSStringFromClass(AppDelegate)會報錯
}
再生成一個ViewController,這個ViewController很類似Android中的Activity。
import?kotlinx.cinterop.*
import?platform.Foundation.*
import?platform.UIKit.*
@ExportObjCClass
class?ViewController?:?UIViewController?{
constructor(aDecoder:?NSCoder)?:?super(aDecoder)
override?fun?initWithCoder(aDecoder:?NSCoder)?=?initBy(ViewController(aDecoder))
@ObjCOutlet
lateinit?var?label:?UILabel
@ObjCOutlet
lateinit?var?textField:?UITextField
@ObjCOutlet
lateinit?var?button:?UIButton
@ObjCAction
fun?buttonPressed()?{
label.text?=?"Konan?says:?'Hello,?${textField.text}!'"
}
}
運行出來的效果如下:
六、Kotlin/Native開發一個地圖Demo
看到上面的運行Demo,大家有沒有在思考一個問題IOS項目中的ViewController是怎么和UI組件綁定在一起的呢?我個人認為這個很重要,換句話說這就是IOS開發最基本的套路,如果這個都不弄明白的話,下面Demo開發就是云里霧里了,掌握了這個基本套路的話,作為一個Android開發者,你基本上就可以在IOS項目開發中任意折騰了。
第一步: 在kotlin目錄下新建一個KNMapViewController類,并且它去繼承UIViewController以及實現MKMapViewDelegateProtocol接口,并重寫viewDidLoad()函數。并且在viewDidLoad函數實現map地圖基本配置。
//導入Kotlin以與Objective-C和一些Cocoa?Touch框架互操作。
import?kotlinx.cinterop.*
import?platform.CoreLocation.CLLocationCoordinate2DMake
import?platform.Foundation.*
import?platform.MapKit.MKCoordinateRegionMake
import?platform.MapKit.MKCoordinateSpanMake
import?platform.MapKit.MKMapView
import?platform.MapKit.MKMapViewDelegateProtocol
import?platform.UIKit.*
@ExportObjCClass//注意:?@ExportObjCClass注解有助于Kotlin創建一個在運行時可查找的類。
class?KNMapViewController:?UIViewController,?MKMapViewDelegateProtocol?{
@ObjCOutlet?//注意:?@ObjCOutlet注解很重要,主要是將mMapView屬性設置為outlet。這允許您將Main.storyboard中的MKMapview鏈接到此屬性。
lateinit?var?mMapView:?MKMapView
constructor(aDecoder:?NSCoder)?:?super(aDecoder)
override?fun?initWithCoder(aDecoder:?NSCoder)?=?initBy(KNMapViewController(aDecoder))
override?fun?viewDidLoad()?{
super.viewDidLoad()
val?center?=?CLLocationCoordinate2DMake(32.07,?118.78)
val?span?=?MKCoordinateSpanMake(0.7,?0.7)
val?region?=?MKCoordinateRegionMake(center,?span)
with(mMapView)?{
delegate?=?this@KNMapViewController
setRegion(region,?true)
}
}
}
第二步: 用Xcode打開項目中的Main.storyboard,刪除原來自動生成一些視圖組件(如果你處于AppCode中開發項目,實際上直接在AppCode中雙擊Main.storyboard就會自動使用Xcode打開當前整個項目,并打開這個項目)
第三步: 給當前空的視圖綁定對應ViewController,這里是KNMapViewController
第四步: 在當前空的視圖中添加一個map view組件并且設置組件的約束條件。
第五步: 右擊組件MKMapView可以看到黑色對話框,里面Referencing Outlets還空的,說明當前ViewController沒有和MKMapView組件綁定
第六步: 配置outlet,這里說下AppCode很坑爹地方,需要手動去source code中手動配置outlet,選中main.storyboard右擊open as 然后選擇打開source code
第七步: 在view和viewController結尾標簽之間配置connection
配置的code如下:
配置結果如下:
第八步: 檢驗是否綁定成功, 回到main.stroyboard視圖,右擊組件查看黑色框是否出現如下綁定關系,出現了則說明配置成功。
Kotlin/Native Demo GitHub
七、Kotlin/Native開發體驗分析
Kotlin/Native目前還是處于1.0的beta,所以還是有很多的地方是不讓人滿意的。下面我總結這次Kotlin/Native開發體驗的優缺點:
通過上述的幾個例子,可以明顯表明Kotlin/Native語言層面跨平臺能力還是很強的,和OC,Swfit項目操作性也很強,該有的基本上都已經實現了,所以對于它后續發展還是非常值得關注的。據我了解到,Kotlin團隊目前首要重心就是在Kotlin/Native這一塊,希望他們能給我們帶來更多關于Kotlin/Native的驚喜。
缺點還是有很多的:
1、Kotlin/Native編譯速度有點慢的驚人,不過運行速度還是不錯的。
2、AppCode中用Kotlin開發IOS項目,沒有很強的代碼提示,很多API導包都比較麻煩,對于初學者更是一臉懵逼。
3、AppCode中的Kotlin/Native插件居然沒提供右鍵創建Kotlin類、接口之類,包括官方也給出這是個問題不過提供一個fix方案。
最后可以測試一下:
4、AppCode中使用Kotlin開發IOS項目,配置outlet還得切換到在Xcode手工操作,希望后續改進。
5、AppCode耗內存還大了,比AndroidStudio還厲害,多開了兩個項目,基本就是每操作IDE就在轉圈圈,希望后續改進。
八、聊點關于Kotlin/Native和Flutter框架那點事
其實關于這個主題,我是不太想去說的,因為我不想引起編程語言界的口戰。但是總有人喜歡去把Kotlin/Native和Flutter放在一起去做對比,因為他們好像都有一個共同點就是跨平臺都能開發Android、IOS應用。并且在此次Jetbrains開發者日上就有參會嘉賓在會上問官方布道師Hali,Kotlin/Native和Flutter有什么不一樣,優勢在哪?
針對這個問題我說下個人的觀點:
首先,我個人是非常看好Flutter這個移動端跨平臺框架,它能夠完全抹平Android,IOS API層面的差異性。換句話說就是一個小白,也許他不懂Java,OC或Swift,他只要熟悉dart并且熟悉Flutter框架API就能開發出Android和IOS兩個原生般體驗的應用。確實很爽啊,無論站在公司節約人力和維護成本還是開發者技術成本角度考慮都是不錯的選擇。可是從另一角度可以想象下一旦形成這樣的局面,很多新項目都是用dart開發,swift和oc語言對于新的開發者而言你會去用嗎? 蘋果爸爸貌似就會不開心了,這其中故事大家可以自己去想像了(當然也許未來不是我說的那樣發展,純屬個人猜想的哈)。
然后,我說下Kotlin/Native吧,其實Kotlin/Native和Flutter不是一個層面東西,不太很好做對比,Kotlin/Native更多的是語言編譯器層面,而Flutter是框架層面。兩者根本就不是一個世界的。Flutter是自己實現一套渲染機制和UI引擎,并且有著豐富Development API。而Kotlin/Native更多關注是編譯器如何將kt源碼編譯成IOS LLVM可運行的二進制碼,但是Kotlin/Native并沒有像Flutter一樣在API層面抹平平臺差異性,而是
在語言層面做了平臺差異性抹平。也就是說你要開發IOS應用不僅會Kotlin/Native還得會IOS 應用開發Development Api. 這貌似Kotlin/Native稍遜Flutter一籌,但是想想也有道理,API層面抹平不是在語言層面職責,還是需要框架層面來做到這一點,說不定哪天Kotlin團隊也造出一個類似Flutter的輪子呢。而且語言層面跨平臺帶來的還有一點好處就是共享代碼,Android、IOS、前端都可以用Kotlin來實現,可以把它們擁有相同邏輯用Kotlin編寫的代碼放入一個common包中統一管理,并且Kotlin對多平臺共享這塊做了很好的支持,然后來自于不同平臺可以共享這塊通用的邏輯實現,不用各自平臺去寫一套了。
通過上述觀點,我們總結到對于開發者而言,學習一門新的技術實際上一般會存在兩層隱形成本。一層是對新的開發語言的掌握,另一層則是對這門技術的Development Api的熟悉和掌握。那么Kotlin/Native就是為了磨平第一層開發語言的障礙。語言層面能做的也只能這樣了,不像Flutter它是一個框架,它可以直接從API層面抹平。如果Flutter最終能推廣起來,在熱更新和熱修復這塊支持比現在的原生還好的話,并且你是一個初學者,那么它絕對是一個不錯的選擇。
如果你是Kotlin開發者,你完全可以使用Kotlin/Native然后花一些時間熟悉下IOS的API也能把IOS應用玩起來。當然Kotlin/Native開發IOS應用只是其中一小部分,你完全用它去做更多有意義的事。
如果你是移動開發者,建議兩門技術都可以去嘗試一下畢竟技多不壓身,當然語言只是一門工具,最終靠還是計算機扎實的基礎、分析需求的能力以及架構項目的功能能力。有了這些能力再加上一個高效的編程語言那么你就更加所向披靡了。
Kotlin系列文章,歡迎查看:
原創系列:
教你如何攻克Kotlin中泛型型變的難點(實踐篇)
教你如何攻克Kotlin中泛型型變的難點(下篇)
教你如何攻克Kotlin中泛型型變的難點(上篇)
Kotlin的獨門秘籍Reified實化類型參數(下篇)
有關Kotlin屬性代理你需要知道的一切
淺談Kotlin中的Sequences源碼解析
淺談Kotlin中集合和函數式API完全解析-上篇
淺談Kotlin語法篇之lambda編譯成字節碼過程完全解析
淺談Kotlin語法篇之Lambda表達式完全解析
淺談Kotlin語法篇之擴展函數
淺談Kotlin語法篇之頂層函數、中綴調用、解構聲明
淺談Kotlin語法篇之如何讓函數更好地調用
淺談Kotlin語法篇之變量和常量
淺談Kotlin語法篇之基礎語法
翻譯系列:
[譯]Kotlin的獨門秘籍Reified實化類型參數(上篇)
[譯]Kotlin泛型中何時該用類型形參約束?
[譯] 一個簡單方式教你記住Kotlin的形參和實參
[譯]Kotlin中是應該定義函數還是定義屬性?
[譯]如何在你的Kotlin代碼中移除所有的!!(非空斷言)
[譯]掌握Kotlin中的標準庫函數: run、with、let、also和apply
[譯]有關Kotlin類型別名(typealias)你需要知道的一切
[譯]Kotlin中是應該使用序列(Sequences)還是集合(Lists)?
[譯]Kotlin中的龜(List)兔(Sequence)賽跑
[譯]Effective Kotlin系列之考慮使用靜態工廠方法替代構造器
[譯]Effective Kotlin系列之遇到多個構造器參數要考慮使用構建器
實戰系列:
用Kotlin擼一個圖片壓縮插件ImageSlimming-導學篇(一)
用Kotlin擼一個圖片壓縮插件-插件基礎篇(二)
用Kotlin擼一個圖片壓縮插件-實戰篇(三)
淺談Kotlin實戰篇之自定義View圖片圓角簡單應用
歡迎關注Kotlin開發者聯盟,這里有最新Kotlin技術文章,每周會不定期翻譯一篇Kotlin國外技術文章。如果你也喜歡Kotlin,歡迎加入我們~~~
Java Kotlin ios
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。