赞
踩
目前仓颉语言只开放了文档,未开放sdk让开发者测试开发。可以申请仓颉的开发者预览版Beta招募,链接Here
类型扩展
添加函数 (swift包含)
仓颉:
extend String {
func printSize() {
print(this.size)
}
}
"123".printSize() // 3
Swift:
extension String {
func printSize() {
print(self.size)
}
}
"123".printSize() // 3
添加属性 (swift不包含)
添加操作符重载 (swift包含)
仓颉: struct Point { let x: Int let y: Int init(x: Int, y: Int) {...} operator func +(rhs: Point): Point { return Point( this.x + rhs.x, this.y + rhs.y ) } } let a: Point = ... let b: Point = ... let c = a + b
Swift: struct Point { let x: Int let y: Int init(x: Int, y: Int) { self.x = x self.y = y } static func +(lhs:Point, rhs: Point) -> Point { return Point(x: lhs.x + rhs.x, y: lhs.y + rhs.y) } } let c: Point = Point(x: 1, y: 1) let d: Point = Point(x: 2, y: 2) let e = c + d
实现接口 (swift包含)
仓颉:
sealed interface Integer {}
extend Int8 <: Integer {}
extend Int16 <: Integer {}
extend Int32 <: Integer {}
extend Int64 <: Integer {}
let a: Integer = 123 // ok
Swift:
protocol Integer {}
extension Int8 : Integer {}
let a :Integer = Int8(123)
代数数据类型和模式匹配
仓颉中的枚举定义与使用:
enum BinaryTree {
| Node(value: Int, left: BinaryTree, right: BinaryTree)
| Empty
}
func sumBinaryTree(bt: BinaryTree) {
match (bt) { //match关键字实际是rust语言中的模式匹配关键字。
case Node(v, l, r) =>
v + sumBinaryTree(l) + sumBinaryTree(r)
case Empty => 0
}
}
Swift中的枚举定义与使用: indirect enum BinaryTree { case Node(value: Int, left: BinaryTree, right: BinaryTree) case Empty } func sumBinaryTree(bt: BinaryTree) -> Int { switch bt { case .Node(let value, let left, let right): return value + sumBinaryTree(bt: left) + sumBinaryTree(bt: right) case .Empty: return 0 } }
泛型
泛型函数的声明方式几乎一样,尤其是针对泛型类型T的限制,两者都使用where关键字。
仓颉:
func lookup<T>(element: T, arr: Array<T>): Bool where T <: Equatable<T> {
for (e in arr){
if (element == e){
return true
}
}
return false
}
Swift:
func lookup<T>(element: T, arr: Array<T>) -> Bool where T : Equatable {
for e in arr {
if (element == e){
return true
}
}
return false
}
命名参数&参数默认值
仓颉:
func dateOf(year!: Int64, month!: Int64, dayOfMonth!: Int64, timeZone!: TimeZone = TimeZone.Local) {
}
dateOf(year: 2024, month: 6, dayOfMonth: 21) // ok
dateOf(year: 2024, month: 6, dayOfMonth: 21, timeZone: TimeZone.UTC) // ok
Swift:
func dateOf(year: Int64, month: Int64, dayOfMonth: Int64, timeZone: TimeZone = TimeZone.current) {
}
dateOf(year: 2024, month: 6, dayOfMonth: 21) // ok
dateOf(year: 2024, month: 6, dayOfMonth: 21, timeZone: TimeZone.gmt) // ok
尾随lambda(trailing lambda)
仓颉:
func unless(condition: Bool, f: ()->Unit) {
if(!condition) {
f()
}
}
int a = f(...)
unless(a > 0) {
print("no greater than 0")
}
Swift:
func unless(condition: Bool, f: () -> Void) {
if !condition {
f()
}
}
unless(condition: true) {
print("no greater than 0")
}
属性
属性的get/set配置。
仓颉: x和y是只读的,只有get实现,而color则是可变的,用mut prop修饰,同时具有get和set实现。 class Point { private let _x: Int private let _y: Int private var _color: String init(x: Int, y: Int, color: String) {...} prop x: Int { get() { Logger.log(level: Debug, "access x") return _x } } prop y: Int { get() { Logger.log(level: Debug, "access y") return _y } } mut prop color: String { get() { Logger.log(level: Debug, "access color") return _color } set(c) { Logger.log(level: Debug, "reset color to ${c}") color = c } } } main() { let p = Point(0, 0, "red") let x = p.x // "access x" let y = p.y // "access y" p.color = "green" // "reset color to green" }
Swift: x和y是只读的,只有get实现,而color则是可变的,同时具有get和set实现。 class Point2 { private let _x: Int private let _y: Int private var _color: String init(_ x: Int, _ y: Int,_ color: String) { self._x = x self._y = y self._color = color } var x: Int { get { return _x } } var y: Int { get { return _y } } var color: String { get { return _color } set(c) { _color = c } } } let p = Point2(0, 0, "red") p.x = 100 //error let x = p.x // "access x" let y = p.y // "access y" p.color = "green" // "reset color to green"
空引用安全
在仓颉中,对于任意类型T,都可以有对应的可选类型Option。具有Option类型的变量要么对应一个实际的具有T类型的值v,因此取值为Some(v),要么具有空值,取值为None。
可选类型(Option)是一种 enum 类型,是一个经典的代数数据类型,表示有值或空值两种状态。
在Swift,用来表示变量可空的关键字为Optional.
仓颉:
var a: ?Int = None
a?.toString() // None
a ?? 123 // 123
a = Some(321)
a?.toString() // Some("321")
a ?? 123 // 321
Swift:
var f: Int? = nil
print(f) //nil
print(f ?? 123) // 123
var g = Optional(321)
print(g) //Optional(321)
print(g ?? 123) // 321
值类型
仓颉和Swift都使用struct来实现用户自定义的值类型。
仓颉:
struct Point {
var x: Int
var y: Int
init(x: Int, y: Int) { ... }
...
}
var a = Point(0, 0)
var b = a
a.x = 1
print(b.x) // 0
Swift:
struct Point {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
var a1 = Point3(x:0,y: 0)
var b1 = a1
a1.x = 1
print(b1.x) // 0
宏
仓颉:
定义一个名为 DebugLog 的宏:
public macro DebugLog(input: Tokens) {
if (globalConfig.mode == Mode.development) {
return quote( println( ${input} ) )
}
else {
return quote()
}
}
使用 DebugLog 宏:
@DebugLog( expensiveComputation() )
Rust:
use proc_macro;
#[some_attribute]
pub fn some_name(input: TokenStream) -> TokenStream {
}
Actor
使用更简洁的语法来实现异步编程、并发编程中的数据竞争问题。
仓颉: actor Account { instance var balance: Int64 init (x: Int64) { this.balance = f1() } instance func performWithdraw(amount: Int64): Unit { balance -= amount } receiver func withdraw(amount: Int64): Bool { if (this.balance < amount) { return false } else { this.performWithdraw(amount); return true } } }
Swift:
注意:这段代码是来自于Swift的官方文档。仓颉的文档示例与swift的文档示例代码基本是一致的,看来仓颉语言应该是参考了Swift语言不少的东西。
actor Account {
var balance: Int = 20// current user balance is 20
// ...
func withdraw(amount: Int) {
guard balance >= amount else {return}
self.balance = balance - amount
}
}
可变性修饰符
可变性修饰符:let 与 var,分别对应不可变和可变属性,
垃圾收集方案
仓颉使用追踪式垃圾回收,类似于java中的基于可达性分析的垃圾回收算法;Swift使用引用计数法。(Swift有weak关键字)
管道(Pipeline)操作符
func double(a: Int) {
a * 2
}
func increment(a: Int) {
a + 1
}
double(increment(double(double(5)))) // 42
5 |> double |> double |> increment |> double // 42
类型扩展可添加属性
try-with-resources
该特性应该借鉴自java.
try (input = MyResource(),
output = MyResource()) {
while (input.hasNextLine()) {
let lineString = input.readLine()
output.writeLine(lineString)
}
}
溢出检查
这个机制使得大多数时候,整数溢出都会及时被感知,避免造成业务隐患。
@OverflowWrapping
func test(x: Int8, y: Int8) { // if x equals to 127 and y equals to 3
let z = x + y // z equals to -126
}
并发编程
线程创建简单且占用内存量小。使用Spawn关键字来创建新线程。
func fetch_data(url: String) { let response = http_get(url) process(response) } main() { let urls = ["https://example.com/data1", "https://example.com/data2", ...] let futures = ArrayList<Future<Unit>>() for (url in urls) { let fut = spawn { fetch_data(url) } // 创建仓颉线程进行网络请求 futures.append(fut) } for (fut in futures) { // 等待所有仓颉线程完成 fut.get() } }
无锁并发对象。
运行时库提供了一系列的原子操作对象,尽量让开发者少使用互斥量或者锁来实现线程安全。同时提供的这些原子操作对象,针对多线程操作做了优化,其效率比单纯使用互斥量要高得多。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。