本文主要是介绍(仓颉) 仓颉语言入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- ⭐前言
- 🔠1 基本概念
- 🔤Hello World
- 🔤标识符
- 🔤内置类型
- 🔤if表达式
- 🔤for表达式
- 🔤while表达式
- 🔤demo 手动计算Π
- 🔠2 函数
- 🔤普通函数
- 🔤lambda
- 🔤demo 递归遍历目录
- 🔠3 枚举
- 🔤enum
- 🔤match表达式
- 🔤option 解析数字
- 🔤demo 计算表达式
- 🔠4 struct
- 🔤值类型
- 🔤二叉树
- 🔠5 calss
- 🔤引用类型
- 🔤继承
- 🔤prop 属性
- 🔠6 接口与扩展
- 🔤interface
- 🔤extend
- 🔤泛型
- 🔠7 异常处理
- 🔤try catch finally
- 🔠8 并发编程
- 🔤Future
- 🔠9 跨语言互操作
- 🔠10 宏
- 🔤macro
- ⭐END
- 🌟交流方式
⭐前言
仓颉-鸿蒙原生应用编程语言-华为开发者联盟 (huawei.com)
初识仓颉语言-仓颉编程语言开发指南-学习仓颉语言 - 华为HarmonyOS开发者 (huawei.com)
【原创】仓颉编程语言入门教程
楼主作为主语言C++,副语言python。仅做基础的入门了解。
本文不做任何格外的语法说明,仅在代码中用简短的注释辅助。
下文均为教学视频中的实例demo(上方的视频也出现在官网的视频一栏中)。
本文所有代码均在下方的在线编译器中进行尝试。
除了最后两章,9,10无法进行单文件操作其余均有验证。
仓颉 Playground (zxilly.dev)
https://github.com/Zxilly/playground-cj
仓颉版本 0.54.3
package cangjie// 编写你的第一个仓颉程序 main(): Int64 {println("你好,仓颉!")return 0 }
🔠1 基本概念
🔤Hello World
// main 可以没有返回值
main() {println("你好,仓颉!")
}
🔤标识符
main() {// 普通变量let num = 10let ___x = "___Str"println(num)println(___x)// 原始表示符// 用于将关键字作为标识符let `for` = "这是一个将for关键字用作原始标识符"println(`for`)
}
🔤内置类型
main() {/*** 字面量后缀* 整形* Int8 -> i8* Uint8 -> u8* 浮点型* Float16 -> f16*/let a: Int64 = 2024let b = 67u8let c: Float64 = 6.21let d: Bool = true || falseprintln(d)// 字符类型,表示一个 unicode 字符// 运行下来双引号也可以运行let e: Rune = '仓'let f: Rune = '\u{9889}'println("${e} ${f}")// 单行字符串let g: String = "Cang" + "jie"let h: String = """第1行,这是多行字符串第2行
"""// 插值字符串// 要求表达式类型实现了 ToString 接口let i: String = "Cangjie${a}"println("${h}${i}")// 引用类型数组let j: Array<UInt8> = [1u8, 2u8]// 值类型数组// 没有 ToString// let k: VArray<Rune, $2> = ['C', 'J']let k: VArray<Rune, $2> = [e, f]println("引用类型数组${j}")// 元组类型let l: (Int64, Float64) = (2024, 9.6)// expected 'Struct-String', found 'Tuple<Int64, Float64>'// println(l)// 区间类型// 主要用于for in表达式中let m: Range<Int64> = 2019..2024// expected 'Struct-String', found 'Struct-Range<Int64>'// println(m)
}
🔤if表达式
import std.random.*main() {let speed = Random().nextFloat64() + 20.0println("${speed} km/s")// if 表达式// 类似于 gcc 中的大括号表达式let level = if (speed > 16.7) {"第3宇宙速度"} else if (speed > 11.2) {"第2宇宙速度"} else if (speed > 7.9) {"第1宇宙速度"} else {"第0宇宙速度"}println(level)
}
🔤for表达式
main() {// 1. forvar sum = 0// range(1, 100, 2)for (i in 1..99 : 2) {sum += i}println(sum)// 2. forlet arr = [(1, 2), (3, 4)]// 元组可以解构for ((x, y) in arr) {println("x=${x} y=${y}")}// 3. forvar num = 2// 用 _ 作为占用,避免编译器警告for (_ in 0..5) {num *= num}// 4. for// 当 where 为 true 才执行循环体for (i in 0..10 where i % 2 == 1) {println(i)}
}
🔤while表达式
main() {var result = 0.0var lower = 1.0var upper = 2.0while (upper - lower > 1.0E-10) {result = (lower + upper) / 2.0if (result ** 2 - 2.0 > 0.0) {upper = result} else {lower = result}}println("√2 ≈ ${result}")
}
🔤demo 手动计算Π
// 在在线仓颉Playground 中运行失败
// from std import random.*
// from std import math.*
import std.random.*
import std.math.*main() {/*** 手动计算圆周率* 在一个正方形中随机投点*/const N = 10000var n: UInt32 = 0let random = Random()for (_ in 0..N) {let x = random.nextFloat64()let y = random.nextFloat64()if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {n++}}let pi = Float64(n) / Float64(N) * 4.0println("Π = ${pi}")println("deviation: ${abs(Float64.PI - pi)}")
}
🔠2 函数
🔤普通函数
func void() {// pass
}// 将函数作为参数
func node(value: Int32, left!: () -> Unit = void, right!: () -> Unit = void) {// 二叉树的中序遍历func show() {left()print(value)right()}return show
}main() {let tree = node(0,left: node(1, left: node(2, right: node(3))),right: node(4, left: node(5), right: node(6)))tree()
}
🔤lambda
func iter(n: Int64, x0: Float64, f: (Float64) -> Float64) {var x = x0for (_ in 0..n) {print("${x}, ")x = f(x)}println("${x}")
}main() {// lambda 表达式// { 参数列表 => 函数体 }// { params => block }// 周期3iter(5, 0.8, {x: Float64 => 1.0 / (1.0 - x)})// 没有周期,产生未随机数iter(10, 0.8, {x: Float64 => 4.0 * x * (1.0 - x)})
}
🔤demo 递归遍历目录
import std.fs.*func forEachFileDo(root: Path, handler: (Path) -> Unit): Unit {let current = Directory(root)for (file in current.files()) {handler(file.path)}for (directory in current.directories()) {forEachFileDo(directory.path, handler)}
}main() {forEachFileDo(Path("."), {path: Path => println(path)})
}
🔠3 枚举
🔤enum
enum Tree {// 枚举项Empty | Leaf(Int64) | Node(Int64, Tree, Tree)// 成员函数public func traverse(): Unit {match (this) {case Empty => ()case Leaf(value) => print(value)case Node(value, left, right) =>left.traverse()print(value)right.traverse()}}public static func generate(depth: UInt8): Tree {if (depth == 1) {return Leaf(1)}return Node(Int64(depth),generate(depth - 1),generate(depth - 1))}
}main() {let tree = Node(1,Node(2, Node(3, Empty, Leaf(4)), Empty),Node(5, Leaf(6), Leaf(7)))tree.traverse()println()let fullTree = Tree.generate(5)fullTree.traverse()
}
🔤match表达式
func fib(n: Int64): Int64 {// math 表达式match (n) {case 0 | 1 => ncase other where other > 0 => fib(other - 1) + fib(other - 2)case _ => 0}
}main() {println(fib(-1))for (i in 1..=10) {print("${fib(i)} ")}
}
🔤option 解析数字
func parseInt(text: String): Option<Int64> {if (text.isEmpty() || text == ".") {return None}var sign = if (text[0] == 45u8) {1} else {0}var sum = 0for (i in sign..text.size) {if (text[i] > 57u8 || text[i] < 48u8) {return None}let digit = Int64(text[i] - 48u8)sum = 10 * sum + digit}// 自动包装为 optionreturn if (sign == 1) {-sum} else {sum}
}main() {let number = parseInt("-123456")// getOrThrow 从 Option 取值println(number.getOrThrow())let result = parseInt("123-456")if (result.isNone()) {println("parse failed")}
}
🔤demo 计算表达式
enum Expr {Num(Float64)| Add(Expr, Expr)| Sub(Expr, Expr)| Mul(Expr, Expr)| Div(Expr, Expr)public func calc(): Float64 {match (this) {case Num(number) => numbercase Add(a, b) => a.calc() + b.calc()case Sub(a, b) => a.calc() - b.calc()case Mul(a, b) => a.calc() * b.calc()case Div(a, b) => a.calc() / b.calc()}}public operator func +(that: Expr): Expr {return Add(this, that)}public operator func -(that: Expr): Expr {return Sub(this, that)}public operator func *(that: Expr): Expr {return Mul(this, that)}public operator func /(that: Expr): Expr {return Div(this, that)}
}main() {let x = Num(1.2) + Num(3.4) + Num(2.0) - Num(1.0) / Num(2.0)println(x.calc())
}
🔠4 struct
🔤值类型
struct Point {static let name = "Point"// 主构造函数// 自动成为成员变量Point(private var x: Float64, private var y: Float64) {println("Create a point: (${x}, ${y})")}public func copy() {return this}// 用 mut 修饰可以使用 this 引用当前实例public mut func set(x: Float64, y: Float64) {this.x = xthis.y = y}public func show() {println("Visit the point: (${x}, ${y})")}
}main() {println(Point.name)let p1 = Point(3.0, 4.0)var p2 = p1.copy()p2.set(1.0, 2.0)p1.show()p2.show()
}
🔤二叉树
struct Node {public Node(var value: Int32, let left!: ?Node = None, let right!: ?Node = None) {}public func traverse(): Unit {// Option 类型的语法糖left?.traverse()print(value)right?.traverse()}static let name: String// 静态构造函数static init() {name = "Binary Tree"}public static func intro() {println(name)}
}main() {Node.intro()let root = Node(1,left: Node(2, left: Node(3, right: Node(4))),right: Node(5, left: Node(6), right: Node(7)))root.traverse()
}
🔠5 calss
🔤引用类型
class Point {static let name = "Point"public Point(private var x: Float64, private var y: Float64) {println("Create a point: {${x}, ${y}}")}// this 是当前的引用public func ref() {return this}public func set(x: Float64, y: Float64) {this.x = xthis.y = y}public func show() {println("Visit the point: (${x}, ${y})")}
}main() {println(Point.name)let p1 = Point(3.0, 4.0)var p2 = p1.ref()p2.set(1.0, 2.0)p1.show()p2.show()
}
🔤继承
// 使用了 open 关键字的才能被继承
open class NodeA {public NodeA(protected var value: String,protected let left!: ?NodeA = None,protected let right!: ?NodeA = None) {}// 中序遍历public open func traverse(): Unit {left?.traverse()print(value)right?.traverse()}
}class NodeB <: NodeA {public init(value: String,left!: ?NodeA = None,right!: ?NodeA = None) {super(value, left: left, right: right)}// 前序遍历public func traverse(): Unit {print(value)left?.traverse()right?.traverse()}
}main() {let root = NodeA('a',left: NodeA('b', left: NodeA('c', right: NodeA('d'))),right: NodeB('e', left: NodeB('f'), right: NodeB('g')))root.traverse()
}
🔤prop 属性
class Node {private var value: Int64 = 0public Node(private var name: String,private let left!: ?Node = None,private let right!: ?Node = None) {}// 是 class 不是 struct// 属性,mut 中才能定义set// 此处属性名:param// 这里的目的是和成员变量 value 进行关联public mut prop param: Int64 {get() {value}set(number) {value = numberupdate()left?.param = number / 2right?.param = number / 2}}private func update() {println("${name} has been updated to ${value}")}
}main() {var root = Node('a',left: Node('b', left: Node('c', right: Node('d'))),right: Node('e', left: Node('f'), right: Node('g')))println(root.param)root.param = 128
}
🔠6 接口与扩展
🔤interface
import std.math.*interface Slot {func compute(t: Float64): Float64operator func <<(that: Slot): Slot {return this}operator func >>(that: Slot): Slot {that << thisreturn this}
}extend Float64 <: Slot {public func compute(t: Float64): Float64 {return this}
}class Wave <: Slot {public Wave(let freq: Float64, let phi: Float64) {}public func compute(t: Float64): Float64 {return sin(2.0 * Float64.PI * freq * t + phi)}
}class Mut <: Slot {public Mut(let a: Slot, let b: Slot) {}public func compute(t: Float64): Float64 {a.compute(t) * b.compute(t)}
}class Integrator <: Slot {var input: ?Slot = Nonevar sum = 0.0public Integrator(let dt: Float64) {}public func compute(t: Float64): Float64 {sum += dt * input.getOrThrow().compute(t)return sum}public operator func <<(that: Slot): Slot {input = Some(that)this}
}main() {const DT = 0.001let left = 1.0 >> Integrator(DT)let right = Wave(0.5 / Float64.PI, 0.0)let flow = Mut(left, right) >> Integrator(DT)for (t in 0..1000) {println(flow.compute(Float64(t) * DT))}
}
🔤extend
// 默认情况下,扩展仅在当前包中有效
extend String {operator func >>(n: Int64): String {if (n <= 0) {return this.clone()}let size = this.sizelet offset = size - n % sizethis[offset..size] + this[0..offset]}
}main() {let text = "Cangjie2024"println(text >> 2 >> 2)
}
🔤泛型
class Node<T> where T <: ToString {public Node(protected var value: T,protected let left!: ?Node<T> = None,protected let right!: ?Node<T> = None) {}// 中序遍历public func traverse(): Unit {left?.traverse()print(value)right?.traverse()}
}main() {let tree1 = Node('a',left: Node('b', left: Node('c', right: Node('d'))),right: Node('e', left: Node('f'), right: Node('g')))tree1.traverse()println()let tree2 = Node(1,left: Node(2, left: Node(3, right: Node(4))),right: Node(5, left: Node(6), right: Node(7)))tree2.traverse()
}
🔠7 异常处理
🔤try catch finally
class ParseException <: Exception {public init() {super("Parse Failed")}
}func parseInt(text: String): Int64 {if (text.isEmpty() || text == ".") {throw ParseException()}var sign = if (text[0] == 45u8) {1} else {0}var sum = 0for (i in sign..text.size) {if (text[i] > 57u8 || text[i] < 48u8) {throw ParseException()}let digit = Int64(text[i] - 48u8)sum = 10 * sum + digit}// 自动包装为 optionreturn if (sign == 1) {-sum} else {sum}
}main() {println(parseInt("-123456"))let number = try {parseInt("123-456")} catch (e: ParseException) {println("not an integer")0}println(number)try {parseInt("123x456")println(parseInt("-123456"))} catch (e: ParseException) {println(e.message)} finally {println("clean up")}// parseInt("x123456")println("end")
}
🔠8 并发编程
🔤Future
import std.collection.*
import std.random.*
import std.math.*const M = 200000
const N = 16func task(): Int64 {var n: Int64 = 0let random = Random()for (_ in 0..M) {let x = random.nextFloat64()let y = random.nextFloat64()if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {n++}}return n
}main() {let futures = ArrayList<Future<Int64>>()for (_ in 0..N) {let future = spawn {task()}futures.append(future)}var n = 0for (future in futures) {n += future.get()}let pi = Float64(n) / Float64(M * N) * 4.0println("Π = ${pi}")println("deviation: ${abs(Float64.PI - pi)}")
}
🔠9 跨语言互操作
🔠10 宏
🔤macro
// macro.cj
// 宏需要定义在宏包
macro package meta
import std.ast.*public macro transform(tokens: Tokens): Tokens {for (token in tokens) {println("${token.value}\t\t${token.kind}")}println("--------------")return tokens
}// main.cj
import meta.*@transform
func add(x: Int64, y: Int64) {return x + y
}main() {@transform(add(1, 2))
}
⭐END
🌟交流方式
⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区
关注我,学习更多C/C++,python,算法,软件工程,计算机知识
B站:
👨💻主页:天赐细莲 bilibili
这篇关于(仓颉) 仓颉语言入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!