typescript写后端的优势是什么?
- 既能用上 JS 庞大的生态
- 又能享受 TypeScript 不输于(甚至碾压)其他静态语言的类型系统
- 有着世界上最庞大的工程师群体,可以跟你交流(/解决问题)
性能?讲真,你接触到的 99% 的项目可能都到不了需要通过切换语言来提高那丁点性能的地步。
而且你再往前看看?Serverless 上不也一样推荐跑 JS,语言(/解释器)上的那点性能损耗真不是事
性能?讲真,你接触到的 99% 的项目可能都到不了需要通过切换语言来提高那丁点性能的地步。
而且你再往前看看?Serverless 上不也一样推荐跑 JS,语言(/解释器)上的那点性能损耗真不是事
首先很抱歉上一篇文章已经胎死腹中。。新的文章已经在酝酿中了,这几天内会发布出来,这篇就当做是给大家的一个新年祝福~顺便写写近期遇到的一些事。
这个我在上一篇(被遗弃的)板凳文里面就提到了,这是我前一段时间一直在捣鼓的一个 IntelliJ IDEA Plugin。我为什么一直在说它呢?因为,,这是非 kotlin 官方团队出的目前唯一一个 Plugin,其余几个 Plugin 都是出自 kotlin 官方团队。
为什么会出现这种情况呢?归根究底,我认为有两个原因:
第二点具体是什么概念?我解释一下,Jetbrains 虽然在 Github 上开源了 kotlin 所有相关的实现,但并没有任何官方 Wiki 对 kotlin-plugin 进行任何接口解释。要写出一个第三方 Plugin 完全靠阅读 JetBrains/kotlin · GitHub 的一大堆源码啊。
当然,最后我还是把它弄出来了 :D。期间有个白俄罗斯的小伙提交了个 Issue,有人反馈的感觉真好~立马修复并更新上 Plugins Repository,目前下载量有两百多(不多,但是在缓步上升),期待能有其他人参与贡献。

近几天,无聊搜了好几个 Android 开发 QQ 群来加。人嘛,都是社群动物,总想和自己领域内的人打打交道。
然而我发现,现在的各种培训班真是无处不在,我 TM 刚进群就几个陌生妹子号开私窗和我唠起来了,先是套近乎,接着「热情」给我推荐各种 Android 在线培训全家桶,只需花个几千块就可两个月内入门 Android 应用开发,一年内月入上万有木有。。


再看看群友们平时都在聊些什么。。。。


大家都在讨论着哪个培训班更便宜、更靠谱,交流着各种培训班的训练项目,讨论的问题也基本上是一些低层次的问题。。
这些无良培训班,打着培训完后月入上万的口号,让多少非专业甚至对编程完全不感兴趣的人涌入开发者市场。本身对编程感兴趣的人就算不上多了,现在还要跟一群其他行业转过来的培训生竞争岗位,也是醉了。
前几个月公司忙着招人的时候,身为面试官,对所有培训班出来的面试者天然降 30 分(真有能力者例外)。并非歧视培训班出来的人,但是培训班出来的,多数要不就是其他专业转过来的,要不就是大学时期没好好学习,工作前还需要再培训。
要知道,并非培训几个月就能熟悉某个领域,更不是做过几个培训项目就有动手能力。问过几个培训班出来的,甚至连很多计算机基础问题都答不出来,整场面试也就只能围绕着他们做的那几个「培训项目」说说。到后来也就疲倦了,凡是看不上的都直接提前中止面试,省得浪费时间。
这年头,比较好的开发者很多都开始移民了,现在给国内这些培训班一搅和,长尾效应更严重了,花个半天时间去逛 CSDN、eoeAndroid 等社区,会发现实在是鱼塘水深。

一直想要写一个能展示自己所有开源项目的网页(GitHub 的 Profile 页有点弱),于是最近用过 Svelte 尝试撸了一个。不得不说 Svelte 确实太妙了,十分接近我心目中的 Web 开发的最佳方案,预计也会成为我之后开发小项目的首选方案 :)
PS:网站需要科学网络访问
上 Twitter 逛了下才发现 Github 十周年!

在做 Annotation Processor 的时候,因为是一个纯的 Java 项目,所以没法直接依赖 Android 的 Aar 包。这件事卡了很久(大概有两周多),最后通过不断看 & Debug Android Gradle Plugin 和 Gradle 自身的代码总算解决了。
国内(乃至世界)范围内精通 Gradle 的人太少了,导致网络上的相关资料特别少。Gradle 里面甚至会涉及到和 IDE(例如 Intellij)的交互,而本身还有 IDE Plugin 和 Tooling API 两套方案,而 IDE Plugin 已经不推荐了也没在官方文档说,导致兜了太多太多弯路。
时隔一年,终究要重新写起 Kotlin,但这次是因为不想写 Js……
Kotlin 1.1 正式版是个令人激动的版本,具体的更新细节可以查看官方博文:Kotlin 1.1 Released with JavaScript Support, Coroutines and more
该来的还是来了。虽然对于 android 来说 coroutine 应该不常用到,coroutine 更适合用在 server 这种 io 密集的应用上。
coroutine 做的其实就是在单线程里替换掉所有 thread.sleep() 函数。例如把 thread.sleep() 换成 asyncio.sleep()。当你需要延时的时候,为什么要调用 thread.sleep() 来阻塞线程呢?还不如用 cpu 来执行程序里的其他代码。所以它把所有 thread.sleep() 替换成 asyncio.sleep(),把所有包含 thread.sleep() 的其他函数(最常见的就是 io 函数)替换成非阻塞的版本。当调用到 asyncio.sleep() 时实际上并不是执行 thread.sleep(),而是保存当前栈然后去执行其他代码,等到恰当时机时再恢复栈继续执行之前的函数。
说起来 coroutine 的实现其实和 android 里的 looper 有点类似,android 是借助 looper 来在单线程里实现异步的,例如 postDelay(),它没有在 postDelay() 里调用 thread.sleep() 来延时,而是把实际要执行的代码扔到事件队列中,等到合适的时机再执行相应的代码,它保证了不会阻塞当前的 main thread。
Running on multiple platforms is a strategic direction for Kotlin. With 1.1 we can run on servers, desktops, Android devices and browsers, but in the future we are going to compile Kotlin to native code and run on many more platforms (including, for example, iOS and embedded devices).
kotlin 未来有望支持编译成 native code,这是个让人十分 excited 的消息。现在已经能将 kotlin 编译成 js 了,未来能编译成 native code 的话,以后你写的代码有望在不借助 jvm 的情况下跑在各个平台下(例如 iOS)。显然 jetbrains 在做一件野心很大的事情,它在尝试让 kotlin 变成更通用的语言。
至于 android 领域,我觉得 android 开发者们现在可以尝试下这门语言了。不用纠结于 google 是否会提供官方支持,按 kotlin 目前的成熟度(要知道 jetbrains 的 ide 技术是世界顶尖的),已经不需要 google 官方给出什么支持了(当然,推广上的支持除外)。虽然国内的开发者可能感觉不到 kotlin 的热度,但是在 reddit 的 android dev 板块上 kotlin 一直是火爆的话题,很多开发者甚至团队都已经用了很长一段时间了。
#性能洁癖 用 dev tools 看了下,antd table 多选时居然整个 table 都会重新渲染一遍?找了下 issue 发现 maintainer 以「v4 支持 virtual list 」为理由把 issue 给关掉了(黑人问号)??virtual list 可以解决 row 多的问题,但是 column 多或者 cell 很重时刷新整个 table 不是一样会卡么…
想做一个去中心化的社交平台。
昨天一天的下载突然上涨了很多。

另外一些基于系统 UI 接口的更高维度封装的框架或库也包含在上面(WPF、MFC、DirectUI)。
回到原题。怎么实现的?要么就用系统的 GUI 接口,要么就用底层的图形接口自己画咯(游戏 UI 都是这么搞的,但通常游戏 UI 也会有更高层封装的库。。)
大公司应该还没有放到生产环境中使用,大都在实验性试探阶段。创业团队的话(例如我们公司)已经在用 90% Kotlin 在开发项目了。
实际体验就是:优雅而舒适
更新: 知乎已经准备开始用了
不管 wangyin 这个人讨不讨喜,但是看他打别人脸还是很精彩。。
说实话,年轻人对前辈还是尊重点好些。不要太 naive。
谢邀。支持接入微信公众号,转换公众号接受的消息为弹幕:
Wechat integration
对于上一期文章末尾讲的 companion 还遗留了一些需要解释的地方。
KotlinClass.doSomething()
KotlinClass.Companion.doSomething()
另外,上期文章末尾在对 companion做解释时,提到了 named object,下面粗略提一下。
例如,我们可以在 Model 类内定义一个实名 object 对象 ModelList,并在每次新建 Model 的时候,将实例加入到 ModelList 中的 list 中。
data class Model(var test1: Int, var test2: Int): Parcelable {
constructor(source: Parcel): this(source.readInt(), source.readInt()) {
ModelList.list.add(this)
}
// ...
object ModelList {
val list = arrayListOf<Model>()
}
}
这样我们就维护了一个 全局的 ModelList 单例。当然,named object 还有其他用处,这里暂且就不细说了。
很抱歉拖了很长一段时间的稿,最近工作较忙,空闲时间较少,故而一直未跟进该系列专栏(好吧,其实是懒)。
另,如果时间充足的话,笔者会考虑再开一个 『使用 python 开发 Web』 系列专栏,初步构想是讲解tornado 的一些初、中级知识。专栏也会涉猎到,但不限于 「爬虫、Web Front-end」 等领域。
当然一切只是空想,事实上有出入的话请别打我 ╮(╯_╰)╭ 笔者是个懒人。
这节将对 kotlin_android_base_framework (以下简称 base_framework) 中的 activity/helper 进行讲解。
base_framework 使用的一个包结构如下:
com.nekocode.baseframework
├─ data
│ ├─ net
│ └─ local
│
├─ presenter
│
├─ ui
│ ├─ activity
│ ├─ adapter
│ ├─ fragment
│ └─ view
│
├─ utils
│
├─ App.kt
└─ Config.kt
为了方便,并没有将 kotlin 源码文件提取到新的 kotlin source 文件夹中。目前暂时混合储存在 java source 文件夹中。
得益于 Java 的继承机制,在 base_framework 中,我们可以实现一个抽象的 BaseActivity 类,并在其中实现一些 Activity 通用的方法(例如实现「应用内 UI 风格统一」),这样我们在添加新 Activity 时,只需要继承 BaseActivity 就能获取统一的 features 和接口。
在 BaseActivity.kt 中已经实现的通用接口:
使用 sendMsg(),sendMsgDelayed() 以及 runDelayed() 来实现 Activity 中异步通知。而继承 BaseActivity 的子类都 必须实现抽象的 handler() 方法,来处理异步传来的消息,例如:
public class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sendMsgDelayed(msg(MSG.SHOW_HELLO), 1000)
}
object MSG {
const val SHOW_HELLO = 0
}
override fun handler(msg: Message) {
when(msg.what) {
MSG.SHOW_HELLO -> showToast("hello")
}
}
}
这样,在 Activity 创建后,会延迟一秒再发送 SHOW_HELLO 消息给自己,这个在很多异步场景下十分实用。例如进行一次异步网络请求,或者其他异步耗时操作时,在操作完成后,可以使用 sendMsg() 通知 Activity 已完成操作。注意:handler() 中的消息处理是在 UI Thread 中完成的。
另外,上面的 showToast() 的用法,可以使用 kotlin 的 Extensions 语法糖来实现:
public fun Context.showToast(any: Any) {
when(any) {
is Int ->
Toast.makeText(this, any, Toast.LENGTH_SHORT).show()
is String ->
Toast.makeText(this, any, Toast.LENGTH_SHORT).show()
}
}
这里,我们为 Context 类拓展了 showToast 外部函数,在 showToast() 内可以通过 this 变量来访问「 showToast() 当前所在 Context 的实例」,于是就可以在所有 Context 类及其子类下,使用我们自定义的 showToast 语法糖:
class ContextA : Context() {
fun toast() {
// normal
Toast.makeText(ContextA.this, "hello", Toast.LENGTH_SHORT).show()
// used extensions
showToast("hello")
}
}
其他的一些关于 Extensions 语法糖的例子可以参考 Sugar.kt (会不断完善),这是 kotlin 中十分强大的 feature,通过为类实现 Extensions 方法,创建各种语法糖,极大地缩减了代码量。
而 Activity 间,可以使用 broadcast() 来广播消息。假如,我们实现了一个 LogoutActivity 用来处理用户的账户登出交互。在登出成功后,可以使用 broadcast() 广播一条 LOGOUT 消息给所有 Activity,通知 Activity 账户已经登出,以便进行相应操作。
public class LogoutActivity : BaseActivity() {
fun logoutSuccess() {
broadcast(msg(BaseActivity.MSG.LOGOUT))
}
override fun handler(msg: Message) {
}
}
回到 BaseActivity.kt 中,我们来看看核心 MyHandler 的具体实现:
abstract class BaseActivity : AppCompatActivity() {
companion object {
private val handlers = arrayListOf<MyHandler>()
class MyHandler : Handler {
private val mOuter: WeakReference<BaseActivity>
constructor(activity: BaseActivity) {
mOuter = WeakReference(activity)
}
override fun handleMessage(msg: Message) {
if(mOuter.get() == null) {
BaseActivity.deleteHandler(this)
return
} else {
// ...
mOuter.get().handler(msg)
}
}
}
}
}
这里,MyHandler 被定义为 MainActivity 的内部类,关于 kotlin 中内部类的详细说明可以看 这里 ,在 kotlin 中,默认不加任何修饰词的内部类,都相当于 Java 中的静态内部类,也就是该内部类不持有外部类的实例。而添加了 inner 修饰词的内部类,会持有外部类的实例,可以通过BaseActivity.this 来访问外部类的实例。
我们在 companion object 中维护了一个静态全局 MyHandler 列表,在 Activity 执行 onCreate() 和 finish() 时分别入列和出列自己的 handler。这样我们就获得了一个动态储存所有运行中 Activity 的 Handler 列表。
当然,维护这个列表是为了实现 Activity 间 boradcast 功能。MyHandler 更详细的逻辑实现请自行看完整代码。
下面,我们来看看 runDelayed() 的具体实现:
public fun runDelayed(runnable: ()->Unit, delayMillis: Int) {
val msg = Message()
msg.what = -101
msg.arg1 = -102
msg.arg2 = -103
msg.obj = runnable
handler.sendMessageDelayed(msg, delayMillis.toLong())
}
这是一个 高阶函数 ,它把 runnable()匿名函数当做参数传入。注意,runnable 的类型定义为 ()->Unit。这个类型表示为:传参为空,返回为 Unit (空返回) 的匿名函数。
这样,我们就可以在 runDelayed() 中用使用 Lambda 表达式 :
runDelayed({ showToast("hello") }, 1000)
相信有不少朋友使用过 gradle-retrolambda 插件,但这是一种侵入式的 lambda 实现模拟。相对来说,kotlin 的原生 lambda 支持显得更为彻底,用起来也更加爽快,要知道 「在 kotlin 中,函数和其他值类型一样是一等公民」。

而 kotlin-android-extensions 已经默认为我们将大部分以前使用匿名类传参的各种系统接口,添加上 lambda 的支持,Cool!(。・`ω´・)
另外,在这里解释一下,我们利用 android.os.Message 中的三个参数来标志这是个带 runnable 的消息,在 MyHandler 处理消息时,通过三个参数标志来判断是否是个带 runnable 的消息,如果是的话,就执行该 runnable 函数:
if (msg.what == -101 && msg.arg1 == -102 && msg.arg2 == -103) {
val runnable = msg.obj as ()->Unit
runnable.invoke()
return
}
这是一个含有单个 Toolbar 和 Fragment 的 Activity 抽象类。在很多场景下,我们仅需要含有单个 Fragment 的 Activity,这时候就可以继承 SingleFragmentActivity:
public class MainActivity : SingleFragmentActivity() {
override val fragmentClass = TestFragment::class.java
override val fragmentBundle = {
null
}
override fun afterCreate() {
toolbar.title = "TestActivity"
}
override fun handler(msg: Message) {
}
}
是的,仅仅需要这几行代码就可以创建一个用 TestFragment 填充的 Activity。
我们来看看布局的具体实现:
relativeLayout {
include<Toolbar>(R.layout.toolbar) {
id = id_toolbar
}.lparams(width = matchParent, height = dip(50))
frameLayout {
id = id_fragment_content
}.lparams(width = matchParent, height = matchParent) {
below(id_toolbar)
}
}
我们使用了 anko 库来用 DSL 描述我们 SingleFragmentActivity 的 UI 布局,关于 anko 更详细介绍请查阅 该处 。
我们在 SingleFragmentActivity 中定义了两个抽象变量 fragmentClass,fragmentBundle(在 kotlin 中,支持在抽象类中定义抽象变量)。这样,我们在子类 override 这两个变量,就可以指定使用哪个 Fragment 来填充 Activity 了。
另外需要说明的两个地方是:
感觉这篇废话有些多了(kotlin 以外的东西讲得有些多),以后会多抽精华的地方来讲。心情好的话,也会讲一下 Android 上的一些东西。但是大家都知道的东西,就不多讲了。
顺便解释下,标题乱起的 =_=
这可以算得上是我写的第一个完整的 Web 页面(源码在页面最底端有链接)。脚本这东西写起来就是比编译型语言爽,容易上瘾。
🔗 Gallery
看了那么多回答,仅从技术层面上给一些看法:
无 root 权限应用有没有可能做到「锁核」?
不可能,核心如何分配是系统底层调度的。
无 root 权限应用有没有可能做到「负优化」至多只用其中几个核心?
开少几个线程就可以了,线程数 >= 分配核心数。
所以单从目前已有的信息来看,是没法百分比确定是哪一方的问题。
反驳下大多数人「搞 IT 依旧是给别人打工」这个观点。那你去路边摆摊自己当老板是不是就不同阶级了?阶级的不同主要体现在拥有资本和社会地位的差异上,不考虑社会地位的情况下,只要收入够高,不管是不是给别人打工一样可以改变阶级。
但不可否认的是,工薪阶级作为被剥削的对象,确实大部分价值被资本控制者夺取了。所以要论快慢的话,当然是成为剥削者能更快地改变阶级。
在安全需求较高的场景下怕受到中间人攻击的话,可以使用安全的 VPN 连接到网络上。
另外,排名第一的通过 ARP 欺骗来实现中间人攻击的套路目测成功率比较低,大多数设备上可能都会安装了防火墙软件。
更直接的中间人攻击(通过物理中间件)会成功率指数上升。
题主说的其实就是 C/S 架构层面的东西,也早就不新奇了,大多数的 C/S 架构产品的通信加密协议复杂多了。要知道「Browser」区别于传统的「Client」的地方在于它没有指定且唯一的「Server」,而且是通过 开放协议(HTTP/HTTPS)访问服务端。
而题主所说的「闭源浏览器」,先不说通信协议闭源,服务端如果不开放出去的话,基本上就是完全的 C/S 架构了,自己公司玩玩可以,就算 Server 端开放出去,闭源的话也很难吸引到开发者,因为对开发者来说,Server 端被垄断且无法定制,机制不透明导致的 BUG 也无法修复。
其实题主会有这样的想法很正常,为什么 Browser 将源码直接对用户开放呢,为什么不加密传输呢?其实,HTTP 可以 gzip 压缩,HTTPS 协议更是只有 Browser 才能解密传输数据,所以事实上是「Browser 提供给用户查看源码的功能」,究其原因,我觉得第一是方便开发者调试,第二是加密措施基本上防不胜防,开发者成千上亿,有一人逆向出来基本上就废了,第三应该就是历史原因了:HTML 文件在早期就是简单地描述页面数据、元素,是解释性语言,并非编译型语言。
有什么好好奇的,internet 并没有你想象那么安全。hacker 只要掌握几个未公布的 system 或者常用 app 的 0day exploit 就可以轻松随便入侵你的设备。
可以参考
例如上面这个最近公布的 android stagefright exploit,只需 hacker 发一条携有特殊格式视频的 mms 给你,就应该可以获取你手机的控制权。
针对上述新闻的描述情况,假设如果受害者是同时更换手机和手机号,却依然被感染的话。有下面几种可能:
顺便说一下。在黑市上,一个高危级别的 0day exploit 可以卖出几十万的价格。其实,对于大多数没有安全意识的人来说,一个有能力的 hacker 想 hack 进你的生活实在是太简单的。
其他很多答案都提到了。关键在于用一种通用的语法来「对数据格式进行描述」,然后针对这种语法实现能够转译成不同编程语言的 code generator。走这条路的比较出名的有 protobuf、graphql 等。
例如,我们公司目前就 allin 了 graphql。通过 gql schema 来确定所有数据的格式,然后通过 code generator 来针对不同语言生成对应的实体/类型代码。如果数据格式需要更新的话,只需要更新 schema,然后不同端(例如前后端)再通过重新生成代码来同步变动。
很多人可能把 graphql 单纯当作前后端通讯的新协议,其实并不完全是的。graphql 本质上是一门数据描述/查询语言,需要数据交互的地方都可以用上,例如你可以在 web 端实现本地的 graphql over local storage。
当然,如果你不同端之间用同一门语言,把数据类型的代码抽到单独的 git repo 然后通过 submodule 的形式来共享也不是不行,不过不太建议(狗头
先说结论:有用。
说说我在前东家知乎的经历。首先我是 @李明亮等100万人 明亮老师内推进去的,后来据我的一位直属 leader(也是当时的面试官)说,我当初面试的效果不是很好,但是还是给机会了(狗头。
而后来在知乎的生涯里,我也内推了好几位小伙伴。其中有两位小伙伴也是面试结果不太好,但是因为我个人对他们比较熟悉,所以跟面试官商量了下也都愿意再给一次机会,后来他们两也都最终收到了 offer。
flutter 真的让人又爱又恨,一个多月没看,生态上一堆 breaking changes,淦
个人认为一个很大原因在文化输出上。东北一直以来对外的文化输出主要在小品、二人转等传统戏剧上,这已经跟不上上流社会的审美了,加上最近在东北大火的各种直播、喊麦,容易被人贴上俗的标签,于是造成了大部分人对东北比较片面的印象。当然,实际中我认识的东北人大多数素质还是很高的。
Kotlin 才刚开始发力你和我说你选的是 Swift?!!
两者间个人更支持 Kotlin,感觉新闻的可靠性也值得怀疑。Swift 无法像 Kotlin 一样与原有的 Java 生态圈交融,而单纯从语法上来讲(Kotlin 和 Swift 的语法有很多相似点),Kotlin 已经足够地解放了开发者的生产力,没必要抛弃 Java/JVM 生态圈(各种 Android 类库)投奔 Swift。
再者,将 Swift 作为 First class langue 的工作量应该挺大的,大概也要花上很长一段时间了。至于其他答主说的 Swift compile to Java Bytecode 是不大可能的。一方面是 Swift 语法上并没有针对 JVM(/Dalvik/ART) 进行适配,可能会产生一些坑(例如泛型),再者就是如果真打算这样做的话,Google 应该是脑进水才不直接选择 Kotlin。。。
前段时间抽空对框架做了些修改,主要包括下面几点:
先来讲讲新添加到 Local Repo 的 Storage.kt ,它简单地封装了 Hawk 来进行本地 Key-Value 类型数据的储存。选择使用 Hawk 取代 Kryo 是因为它有以下的一些 features:
当然,付出的代价就是速度降低了,但是它在反序列化时不像 Kryo 那样需传入类型的 class 对象:
// Before
val strtest = Cache["test", String::class.java]
// After
val model: Model.ParcelableTest? = Storage["test"]
Hawk 是使用 Java 编写的。我们可以创建一个 Storage 类并重载 Kotlin 中的 [ ] 操作符,来实现以下的调用:
Storage["test"] = Model(5, 1)
var test: Model? = Storage["test"]
我在前几篇文章中已经对 companion object 做了些介绍:
public class Storage {
companion object {
fun init(context: Context) {
Hawk.init(context)
.setEncryptionMethod(HawkBuilder.EncryptionMethod.MEDIUM)
.setStorage(HawkBuilder.newSqliteStorage(context))
.setLogLevel(LogLevel.FULL)
.build();
}
operator fun set(key: String, obj: Any?) {
if(obj != null) {
Hawk.put(key, obj)
} else {
Hawk.remove(key)
}
}
operator fun <T> get(key: String): T? = Hawk.get(key)
}
}
companion object 是 Storage 类的伴生对象,它在类加载时就生成,具体实现其实就是在该类中添加一个静态子类 Companion,所以在 companion object 中的方法是 Storage 类的静态方法。
另外我们使用 operator 关键字修饰 get 和 set 方法来实现重载 Storage 的 [ ] 操作符,一些常见的可重载操作符以及其对应的转译方法:

更多可重载操作符请查阅 Operator overloading 。
在 base_framework 中我使用了 Retrofit 来与服务端进行交互,并使用了提供的 Gson Converter 来进行内部的隐藏的 Json 数据与实体类之间的转换。
之前是用 Java Class 来当作实体类,后来测试了下,Kotlin 下的 Data Class 也能在 Gson 下正常转换,内嵌也没问题,于是我把原先的 Weather.java 删除掉,用下面一个全局单例的 Model 对象来保存各种实体类:
object Model {
data class WeatherInfo(val city: String)
data class Weather(@SerializedName("weatherinfo") val weatherInfo: WeatherInfo)
}
注意一下 Gson 的 SerializedName 注解 可添加在 Data Class 的 Primary Constructor 中的对应属性声明前。而且注意一下,这里在 Weather 类中包含了同样为 Data Class 类型的 weatherInfo 属性,Gson 一样可以正常地转换,所以,没什么理由继续用 Java Class(又长又臭)了。
已经开始带着一个 Team 在实践 Kotlin 到最近一个的项目中,到目前为止,已经产出了一些挺有趣的东西,有空会继续分享出来。
=== 11/6 更新 ===
有评论问到有 Github 账号的潜台词。
以下是我的回答,望能从中参考一二:
『我认识 github,我懂得在上面能找到高质量的开源代码,我会 git,我有代码能让你看』。不管你有没有共享代码,从你 star 的项目,面试官也能对你知个一二。
=============
有 Github,Blog,Stackoverflow,甚至知乎等账号的都有加分。我司很多情况下筛选的标准就是先看有没有 Github 账户,没的话就看项目经验,项目经验一般的就直接筛掉了。
学不学 python 只看你有否兴趣,是发自于自身学习欲望的,不应该和你的职业规划过度或者说过早挂钩,理论上 java 还有很多你可以深入学习的地方。正面回答题主问题的话:
称职的程序员至少掌握两门以上的语言(编译型语言 & 解析型语言),以题主情况而言,建议先继续深入学习 java,同时可尝试下 python,等认为 python 可以作为自己主要技术栈语言的时候再去考虑是否换职。
本人就是学习过 vb(6),c++,lua,java,python,kotlin 才确定目前主要技术栈的,工作还工作,兴趣还兴趣,学习还学习。
想啥呢,nodejs 只能节省了你再学习一门语言的时间,而这个时间成本很低的,相对而言,领域知识的学习成本才是最高的(狗头
有对应编译器 / 解释器 / 运行时的话,你甚至可以用任何语言去做任何事情。nodejs 的出现更大的意义是帮助完善了前端工具链,让前端工程师有能力对前端进行工程化。