<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rory-lhj</title>
    <description>The latest articles on DEV Community by Rory-lhj (@rorylhj).</description>
    <link>https://dev.to/rorylhj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3191498%2F137af943-175b-4fda-ab63-279aedec11a9.png</url>
      <title>DEV Community: Rory-lhj</title>
      <link>https://dev.to/rorylhj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rorylhj"/>
    <language>en</language>
    <item>
      <title>HarmonyOSNext-The Principles of Decorators in HarmonyOS and Custom Decorators</title>
      <dc:creator>Rory-lhj</dc:creator>
      <pubDate>Wed, 04 Jun 2025 11:40:44 +0000</pubDate>
      <link>https://dev.to/rorylhj/harmonyosnext-the-principles-of-decorators-in-harmonyos-and-custom-decorators-1gg0</link>
      <guid>https://dev.to/rorylhj/harmonyosnext-the-principles-of-decorators-in-harmonyos-and-custom-decorators-1gg0</guid>
      <description>&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What are Decorators in HarmonyOS?
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
In ArkTS, Decorators are special declarations that annotate and modify classes, methods, properties, etc.&lt;/p&gt;

&lt;p&gt;As an extended programming language based on TypeScript, ArkTS inherits TypeScript's decorator support. They are tools for metaprogramming, enabling developers to add extra functionality without altering original code structures. For example, in HarmonyOS development, decorators define component properties, lifecycle methods, etc. The @Component decorator marks a class as a HarmonyOS component class.&lt;/p&gt;

&lt;p&gt;Key decorators in HarmonyOS include:&lt;/p&gt;

&lt;p&gt;State Decorators (V1 &amp;amp; V2): State, Prop, Link, ObservedV2, etc.&lt;br&gt;
Component Decorators: Entry、 CustomDialog、 Component, Builder, etc.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Basic Principles of Decorators
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
ArkTS implements decorators as functions that extend code non-invasively. They fall into three main types:&lt;br&gt;
Class Decorators&lt;br&gt;
Declared above classes, they take the class constructor as an argument and can:&lt;/p&gt;

&lt;p&gt;Modify the class constructor&lt;br&gt;
Add properties and methods to the class&lt;br&gt;
Attach metadata annotations to the class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function logDecorator(constructor: Function) {
  console.log(`Class ${constructor.name} is created.`);
}

@logDecorator
class MyComponent {
  constructor() {
    console.log('MyComponent instance is created.');
  }
}

const myComponent = new MyComponent();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method Decorators are applied to class methods and execute when the method is defined. They accept three parameters: the target object, the method name, and the method descriptor. Method decorators can modify method behavior, such as adding logging, performing permission checks, or implementing throttling/debouncing. In the OpenHarmony open-source system, referring to the system camera source code, a custom method decorator is implemented as follows. However, in HarmonyOS, ArkTS fails strict type checking for any, rendering this syntax incompatible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Log } from '../../utils/Log';

const TAG = '[Decorators]:'

export function debounce(timeout: number) {
  return function inner(target: any, propKey: string, descriptor: PropertyDescriptor) {
    let curFunc: number = 0;
    const original = descriptor.value;
    descriptor.value = function (...args: string[]) {
      Log.log(`${TAG} debounce invoke ${propKey} curFunc: ${curFunc}`);
      curFunc &amp;amp;&amp;amp; clearTimeout(curFunc);
      curFunc = setTimeout(() =&amp;gt; original.call(this, ...args), timeout);
    };
  };
}

export function throttle(waitTime: number) {
  return function inner(target: any, propKey: string, descriptor: PropertyDescriptor) {
    let lastTime: number = 0;
    const original = descriptor.value;
    descriptor.value = function (...args: string[]) {
      let curTime = Date.now();
      Log.log(`${TAG} throttle invoke ${propKey} timeInterval: ${curTime - lastTime}`);
      if (curTime - lastTime &amp;gt;= waitTime) {
        original.call(this, ...args);
        lastTime = curTime;
      }
    };
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Property Decorators are applied to class properties and execute when the property is defined. They accept two parameters: the target object and the property name. Property decorators can modify property accessors, such as adding validation logic or implementing caching. However, in HarmonyOS, ArkTS fails strict type checking for any, rendering this syntax incompatible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function positiveNumber(target: any, propertyKey: string) {
  let value: number;
  const getter = function () {
    return value;
  };
  const setter = function (newValue: number) {
    if (newValue &amp;lt; 0) {
      throw new Error(`${propertyKey} must be a positive number.`);
    }
    value = newValue;
  };
  Object.defineProperty(target, propertyKey, {
    get: getter,
    set: setter,
    enumerable: true,
    configurable: true
  });
}

class MyModel {
  @positiveNumber
  age: number = 20;
}

const myModel = new MyModel();
myModel.age = -1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;3. How to Define Custom Decorators in HarmonyOS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As discussed, HarmonyOS enforces strict ArkTS syntax rules where any and unknown types are disallowed. Therefore, we must use Object to replace the any type for the target parameter.&lt;/p&gt;

&lt;p&gt;The value property in PropertyDescriptor is also of type any, which works in standard TypeScript but requires a workaround in ArkTS. We achieve this by accessing the value property via the Function type, then assigning target: Object, key: string, and descriptor: PropertyDescriptor using the rest parameters syntax (...args).&lt;/p&gt;

&lt;p&gt;...args is the rest parameters syntax in JavaScript and TypeScript (upon which ArkTS is based).&lt;/p&gt;

&lt;p&gt;To define a class decorator in HarmonyOS, follow this pattern. The same principle applies to custom property decorators:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function methodLogger(target: Object, key: string, descriptor: PropertyDescriptor) {
  const originalMethod: Function = descriptor.value;
  descriptor.value = (...args: Object[]) =&amp;gt; {

    console.log(`Calling ${target.constructor.name} method ${key} with argument: ${args}`)
    const result: Object = originalMethod(...args)
    console.log(`Method ${key} returned: ${result}`)
    return result
  }
  return descriptor;
}

@Entry
@Component
struct DecoratorDemoComponent {
  @State message: string = 'Hello HarmonyOS';


  @methodLogger
  private processData(input: string): string {
    console.log('doing...');
    return `：${input.toUpperCase()}`;
  }


  aboutToAppear() {
    const processedResult: string = this.processData('decorator demo');
    console.log('res：', processedResult);
    this.message = processedResult;
  }

  build() {
    Column({ space: 30 }) {
      Text(this.message)
        .fontSize(24)
        .margin(10);

      Button('fun1')
        .onClick(() =&amp;gt; this.processData('button click'))
        .margin(10);
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>HarmonyOSNext — — Cangjie Basic Syntax and Structure</title>
      <dc:creator>Rory-lhj</dc:creator>
      <pubDate>Thu, 22 May 2025 12:48:51 +0000</pubDate>
      <link>https://dev.to/rorylhj/harmonyosnext-cangjie-basic-syntax-and-structure-2ln6</link>
      <guid>https://dev.to/rorylhj/harmonyosnext-cangjie-basic-syntax-and-structure-2ln6</guid>
      <description>&lt;p&gt;This article will delve into the basic syntax and structure of the Cangjie language. These fundamental knowledge lay a solid foundation for writing efficient and maintainable code. By understanding statement structures, expressions, comments, and data types, you can use Cangjie for programming with greater confidence.&lt;br&gt;
Keywords&lt;br&gt;
Cangjie basic syntax&lt;br&gt;
Statement structure&lt;br&gt;
Expression&lt;br&gt;
Comment&lt;br&gt;
Data type&lt;br&gt;
Control structure&lt;/p&gt;

&lt;p&gt;I. Basic Syntax&lt;br&gt;
1.1 Statement Structure&lt;br&gt;
The statement structure in Cangjie forms the fundamental building blocks of code, including assignment statements, conditional statements, and loop statements.&lt;/p&gt;

&lt;p&gt;Assignment Statements: Used to assign values to variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let x: Int64 = 10
println(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output:10&lt;/p&gt;

&lt;p&gt;Conditional Statements: Used to control the execution flow of a program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (x &amp;gt; 0) {
    println("x is +")  
}
output: x is +

for (i in 1..=5) {
    println(i) 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output: 1 2 3 4 5&lt;/p&gt;

&lt;p&gt;Please translate the following text into English.&lt;/p&gt;

&lt;p&gt;1.2 Expressions&lt;br&gt;
Cangjie supports various expressions, including arithmetic operations and logical operations.&lt;/p&gt;

&lt;p&gt;Arithmetic Operations: Such as addition, subtraction, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a: Int64 = 1
let b: Int64 = 2
let sum: Int64 = a + b
println(sum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output:3&lt;/p&gt;

&lt;p&gt;Logical Operations: Such as AND, OR, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (a &amp;gt; 0 &amp;amp;&amp;amp; b &amp;lt; 10) {
    println("a &amp;gt; 0 &amp;amp;&amp;amp; b &amp;lt; 10") 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output:a &amp;gt; 0 &amp;amp;&amp;amp; b &amp;lt; 10&lt;/p&gt;

&lt;p&gt;II. Variable Naming and Identifiers Overview&lt;br&gt;
In the Cangjie programming language, developers assign names to program elements, which are called identifiers. Identifiers are categorized into ordinary identifiers and raw identifiers, each adhering to distinct naming rules.&lt;/p&gt;

&lt;p&gt;III. Comments&lt;br&gt;
Comments are used to improve code readability and maintainability. In Cangjie, there are two types of comments:&lt;/p&gt;

&lt;p&gt;3.1 Single-Line Comments&lt;br&gt;
Single-line comments use // and can be used to explain code or temporarily block code lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;println("Welcome to Cangjie!")
output:Welcome to Cangjie!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.2 Multi-Line Comments&lt;br&gt;
Multi-line comments are enclosed within /* */ and are suitable for longer explanations or blocking multiple lines of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
func factorial(n: Int): Int {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IV. Data Types&lt;br&gt;
Cangjie supports several data types, including:&lt;/p&gt;

&lt;p&gt;Integer Types、Floating-Point Types、String Type、Boolean Type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let age: Int64 = 25
let height: Float64 = 1.75
let name: String = "Cangjie" 
let isAdult: Bool = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;V. Control Structures&lt;br&gt;
Control structures are used to manage the execution flow of a program, including conditional logic and loop constructs.&lt;/p&gt;

&lt;p&gt;Use if, else if, and else for conditional judgment.&lt;/p&gt;

&lt;p&gt;The for loop and while loop are used to repeatedly execute code blocks.&lt;/p&gt;

&lt;p&gt;Summary&lt;br&gt;
This article provides a comprehensive introduction to the basic syntax and structure of the Cangjie language, including statement structures, expressions, comments, data types, and control structures. Mastering these fundamental concepts will lay a solid foundation for subsequent programming learning and serve as the basis for creating efficient and maintainable code.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>HarmonyOSNext——Write the First Cangjie Program</title>
      <dc:creator>Rory-lhj</dc:creator>
      <pubDate>Thu, 22 May 2025 11:43:42 +0000</pubDate>
      <link>https://dev.to/rorylhj/harmonyosnext-write-the-first-cangjie-program-1a5</link>
      <guid>https://dev.to/rorylhj/harmonyosnext-write-the-first-cangjie-program-1a5</guid>
      <description>&lt;p&gt;This article details the entire process of creating the first Cangjie project, writing, and running the first Cangjie program on the Mac system. It covers project creation, code writing, program running and debugging, as well as rerunning after code modifications. Through this article, you will master the basic operations of Cangjie projects, further consolidate the configuration of the development environment, and take the first step in Cangjie programming.&lt;/p&gt;

&lt;p&gt;Keywords&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cangjie program writing&lt;/li&gt;
&lt;li&gt;First Cangjie project creation&lt;/li&gt;
&lt;li&gt;Cangjie code debugging&lt;/li&gt;
&lt;li&gt;VSCode usage guide&lt;/li&gt;
&lt;li&gt;Mac Cangjie development&lt;/li&gt;
&lt;li&gt;Cangjie project running&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  I. Create the First Cangjie Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.1 Create a Project&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open VSCode and use the shortcut Shift + Command + P to open the command palette.&lt;/li&gt;
&lt;li&gt;Type cangjie and select the Create Cangjie Project option.&lt;/li&gt;
&lt;li&gt;Select the "Create CJNative Cangjie Project" option.&lt;/li&gt;
&lt;li&gt;In the pop-up menu, select the "Create Executable Output Cangjie Project" option.&lt;/li&gt;
&lt;li&gt;Select the project path, such as /Users/username/Projects/CangjieProject, enter the project name, and then press Enter.&lt;/li&gt;
&lt;li&gt;After confirming the creation, the main.cj file will be automatically generated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;1.2 Open the Project&lt;/strong&gt;&lt;br&gt;
Open the project folder using VSCode.&lt;/p&gt;

&lt;p&gt;In the Explorer sidebar, navigate to the src/main.cj file and view the default code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main(): Int64 {
    println("hello world")
    return 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1.3 Run the Project&lt;/strong&gt;&lt;br&gt;
1.3.1 Configure the Environment&lt;br&gt;
Open the terminal in VSCode.&lt;/p&gt;

&lt;p&gt;Enter the following command to configure the environment:&lt;br&gt;
&lt;code&gt;source /Users/cangjie/envsetup.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3.2 Execute the Program&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enter the following command in the terminal to run the project:&lt;br&gt;
&lt;code&gt;cjpm run&lt;/code&gt;&lt;br&gt;
Check the terminal output to ensure it displays:&lt;br&gt;
&lt;code&gt;hello world&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3.3 Modify and Rerun the Program&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the src/main.cj file and modify the println statement, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main(): Int64 {
    println("hello world")
    return 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After saving the file, return to the terminal and ensure the environment is configured (if not, re-execute the source command).&lt;/p&gt;

&lt;p&gt;Run the program again:&lt;br&gt;
&lt;code&gt;cjpm run&lt;/code&gt;&lt;br&gt;
Check the terminal output to ensure it displays:&lt;br&gt;
&lt;code&gt;hello world&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  II. Code Debugging
&lt;/h2&gt;

&lt;p&gt;Debugging is an essential part of the programming process, enabling you to efficiently identify and fix errors in your code. Below are the steps to debug a Cangjie program in VSCode:&lt;br&gt;
&lt;strong&gt;2.1 Set Breakpoints&lt;/strong&gt;&lt;br&gt;
Open the src/main.cj file.&lt;br&gt;
Click on the left side of the code line where you want to pause execution to set a breakpoint. For example, set a breakpoint on the line println("hello world").&lt;br&gt;
&lt;strong&gt;2.2 Start Debugging&lt;/strong&gt;&lt;br&gt;
In VSCode, click the Run and Debug icon in the left activity bar or use the shortcut Control + Shift + D.&lt;br&gt;
Click the Start Debugging button (green arrow) or press F5.&lt;br&gt;
The program will run and pause at the breakpoint, allowing you to inspect variables and the program state.&lt;br&gt;
&lt;strong&gt;2.3 Inspect Variables and Call Stack&lt;/strong&gt;&lt;br&gt;
While paused at a breakpoint, use the Variables panel to view current variable values.&lt;br&gt;
Use the Call Stack panel to trace the sequence of function calls.&lt;br&gt;
Step through the code using Step Over (F10), Step Into (F11), and Step Out (Shift + F11).&lt;br&gt;
&lt;strong&gt;2.4 End Debugging&lt;/strong&gt;&lt;br&gt;
Click the Stop button or use the shortcut Shift + F5 to terminate the debugging session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This guide walked you through creating your first Cangjie project, verifying the correct configuration of your development environment, and successfully writing, running, and modifying your first Cangjie program. These steps lay a solid foundation for Cangjie development and introduce code debugging in VSCode to enhance programming efficiency and code quality.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>HarmonyOSNext-The Basic Composition of a Cangjie Program</title>
      <dc:creator>Rory-lhj</dc:creator>
      <pubDate>Thu, 22 May 2025 09:58:54 +0000</pubDate>
      <link>https://dev.to/rorylhj/harmonyosnext-the-basic-composition-of-a-cangjie-program-3e03</link>
      <guid>https://dev.to/rorylhj/harmonyosnext-the-basic-composition-of-a-cangjie-program-3e03</guid>
      <description>&lt;p&gt;This article systematically introduces the basic components of a program in the Cangjie programming language, covering the definition of the main function, the use of packages and modules, variable types, scope, and code structure principles. It aims to help developers understand the overall structure of Cangjie programs and adopt best practices in software design. Understanding these components is essential for writing clean, maintainable, and modular code in Cangjie.&lt;/p&gt;

&lt;p&gt;🔑 Keywords&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Program entry point&lt;/li&gt;
&lt;li&gt;Main function&lt;/li&gt;
&lt;li&gt;Packages and modules&lt;/li&gt;
&lt;li&gt;Variable types and scope&lt;/li&gt;
&lt;li&gt;Value types and reference types&lt;/li&gt;
&lt;li&gt;Code structure and specifications&lt;/li&gt;
&lt;li&gt;Mutability and visibility control&lt;/li&gt;
&lt;li&gt;Top-level declarations and type definitions
I. Program Entry Point and Main Function
In Cangjie, the main function serves as the entry point of a program and is responsible for initializing runtime logic and signaling exit status.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.1 Definition of the Main Function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main(): Int64 {
    return 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple main function returns 0, indicating a successful termination. Like in other statically typed languages, return values from main() help indicate success or failure to the operating system or invoking shell.&lt;/p&gt;

&lt;p&gt;1.2 Parameters and Return Values&lt;br&gt;
The main function can optionally receive arguments via an Array parameter.&lt;/p&gt;

&lt;p&gt;The return type is typically Int64 but may also be Unit if no explicit exit code is required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main(args: Array&amp;lt;String&amp;gt;): Int64 {
    println("Received ${args.length} arguments.")
    return 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Arguments are passed when executing the program from a shell or script environment.&lt;/p&gt;

&lt;p&gt;II. Packages and Modules&lt;br&gt;
Modular programming in Cangjie is achieved using packages and modules, allowing better code organization and reusability.&lt;/p&gt;

&lt;p&gt;2.1 Defining Packages&lt;br&gt;
Use the package keyword at the top of the file to declare a package:&lt;/p&gt;

&lt;p&gt;package cjcDemo&lt;br&gt;
Packages are typically structured based on project hierarchy and logical function grouping.&lt;/p&gt;

&lt;p&gt;2.2 Importing Modules&lt;br&gt;
Use the import keyword to include other modules or libraries:&lt;/p&gt;

&lt;p&gt;import std.math.*&lt;br&gt;
import utils.io.FileReader&lt;br&gt;
🔍 Wildcard imports are supported (*), but it's recommended to import only required symbols to maintain clarity and avoid naming conflicts.&lt;/p&gt;

&lt;p&gt;III. Program Structure and Top-Level Scope&lt;br&gt;
Cangjie program files use the .cj extension. The top-level scope allows declarations of global constants, functions, and types that are accessible across the file or package.&lt;/p&gt;

&lt;p&gt;3.1 Global and Local Scope&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
let globalVar = 2023

func globalFunc() {
    println(globalVar)
}

main(): Int64 {
    globalFunc()
    return 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Global variables are accessible throughout the file or module.&lt;/p&gt;

&lt;p&gt;Local variables declared within a function or block are only valid within that context.&lt;/p&gt;

&lt;p&gt;3.2 Nested Scope and Shadowing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let x = 10
func testScope() {
    let x = 5  // Shadows outer x
    println(x) // Prints 5
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inner variables with the same name override outer definitions within their local scope.&lt;/p&gt;

&lt;p&gt;IV. Variable Definition and Usage&lt;br&gt;
Cangjie variables are defined with strong typing and explicit mutability.&lt;/p&gt;

&lt;p&gt;4.1 Modifiers&lt;br&gt;
let – immutable constant&lt;/p&gt;

&lt;p&gt;var – mutable variable&lt;/p&gt;

&lt;p&gt;public / private – visibility control&lt;/p&gt;

&lt;p&gt;static – shared at the type level&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;cj&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a: Int64 = 20
var b: Int64 = 12
b = 23
println("${a} ${b}")
Output: 20 23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Best practice: use let by default unless mutation is required.&lt;/p&gt;

&lt;p&gt;V. Value vs Reference Types&lt;br&gt;
Cangjie distinguishes between value types (e.g., Int64, Bool) and reference types (e.g., class, struct with heap semantics). Understanding this distinction is important for performance tuning and memory safety.&lt;/p&gt;

&lt;p&gt;cj&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Point {
    x: Int64
    y: Int64
}

class User {
    name: String
    score: Int64
}

main(): Int64 {
    let p = Point(x: 3, y: 4)
    let u = User(name: "Alice", score: 95)

    println("Point: (${p.x}, ${p.y})")
    println("User: ${u.name} scored ${u.score}")
    return 0
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;struct creates value types (copied on assignment).&lt;/p&gt;

&lt;p&gt;class creates reference types (shared references).&lt;/p&gt;

&lt;p&gt;By mastering these fundamentals, developers can confidently build scalable and maintainable Cangjie programs across various domains such as systems programming, education, and cloud-native development.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>HarmonyOSNext -Schedule Management</title>
      <dc:creator>Rory-lhj</dc:creator>
      <pubDate>Wed, 21 May 2025 13:10:43 +0000</pubDate>
      <link>https://dev.to/rorylhj/harmonyosnext-schedule-management-4lhk</link>
      <guid>https://dev.to/rorylhj/harmonyosnext-schedule-management-4lhk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Schedule Management&lt;/strong&gt;&lt;br&gt;
A schedule refers to the arrangement of specific events or activities. Schedule management involves planning and controlling these events and activities to more effectively utilize relevant resources, improve productivity and efficiency, and enable people to better manage their time and tasks.&lt;br&gt;
In Calendar Kit, a schedule [Event] belongs to a corresponding calendar account [Calendar]. A calendar account can contain multiple schedules, and each schedule belongs to only one Calendar.&lt;br&gt;
Once the calendar account object is obtained, you can manage the schedules under that account, including creating, deleting, modifying, and querying schedules. When creating or modifying a schedule, you can set relevant information such as the schedule's title, start time, end time, type, location, reminder time, and recurrence rules to achieve richer and more effective schedule management.&lt;/p&gt;
&lt;h2&gt;
  
  
  Development Steps
&lt;/h2&gt;

&lt;p&gt;1、Import relevant dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// entry/src/main/ets/entryability/EntryAbility.ets
import {abilityAccessCtrl,AbilityConstant, common, PermissionRequestResult, Permissions, UIAbility, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { calendarManager } from '@kit.CalendarKit';
import { window } from '@kit.ArkUI';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、Request Permissions. When using Calendar Kit, you need to declare the permissions required for reading and writing calendar schedules in module.json5: ohos.permission.READ_CALENDAR and ohos.permission.WRITE_CALENDAR.&lt;br&gt;
3、Obtain the Calendar Manager Object. Retrieve the calendar manager object calendarMgr based on the context to manage calendar accounts. This operation is recommended in the EntryAbility.ets file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// entry/src/main/ets/entryability/EntryAbility.ets
export let calendarMgr: calendarManager.CalendarManager | null = null;

export let mContext: common.UIAbilityContext | null = null;

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    console.info("Ability onCreate");
  }

  onDestroy(): void {
    console.info("Ability onDestroy");
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    console.info("Ability onWindowStageCreate");
    windowStage.loadContent('pages/Index', (err, data) =&amp;gt; {
      if (err.code) {
        console.error(`Failed to load the content. Code: ${err.code}, message: ${err.message}`);
        return;
      }
      console.info(`Succeeded in loading the content. Data: ${JSON.stringify(data)}`);
    });
    mContext = this.context;
    const permissions: Permissions[] = ['ohos.permission.READ_CALENDAR', 'ohos.permission.WRITE_CALENDAR'];
    let atManager = abilityAccessCtrl.createAtManager();
    atManager.requestPermissionsFromUser(mContext, permissions).then((result: PermissionRequestResult) =&amp;gt; {
      console.log(`get Permission success, result: ${JSON.stringify(result)}`);
      calendarMgr = calendarManager.getCalendarManager(mContext);
    }).catch((error: BusinessError) =&amp;gt; {
      console.error(`get Permission error, error. Code: ${error.code}, message: ${error.message}`);
    })
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    console.info("Ability onWindowStageDestroy");
  }

  onForeground(): void {
    // Ability has brought to foreground
    console.info("Ability onForeground");
  }

  onBackground(): void {
    // Ability has back to background
    console.info("Ability onBackground");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4、Create a Calendar object based on calendar account information to manage schedules. Configure calendar settings, such as enabling schedule reminders and setting the calendar account color as needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Index.ets
import { BusinessError } from '@kit.BasicServicesKit';
import { calendarMgr } from '../entryability/EntryAbility';
import { calendarManager } from '@kit.CalendarKit';

let calendar: calendarManager.Calendar | undefined = undefined;
const calendarAccount: calendarManager.CalendarAccount = {
  name: 'MyCalendar',
  type: calendarManager.CalendarType.LOCAL,
  displayName: 'MyCalendar'
};
const config: calendarManager.CalendarConfig = {
  enableReminder: true,
  color: '#aabbcc'
};
calendarMgr?.createCalendar(calendarAccount).then((data: calendarManager.Calendar) =&amp;gt; {
  console.info(`Succeeded in creating calendar data-&amp;gt;${JSON.stringify(data)}`);
  calendar = data;

  calendar.setConfig(config).then(() =&amp;gt; {
    console.info(`Succeeded in setting config, data-&amp;gt;${JSON.stringify(config)}`);
  }).catch((err: BusinessError) =&amp;gt; {
    console.error(`Failed to set config. Code: ${err.code}, message: ${err.message}`);
  });
  // ...
}).catch((error: BusinessError) =&amp;gt; {
  console.error(`Failed to create calendar. Code: ${error.code}, message: ${error.message}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5、To add a calendar event under the current calendar account, note that the event ID does not need to be filled in the input parameters.&lt;br&gt;
When creating an event, you can set relevant information such as the event title, start time, end time, event type, location, reminder time, and recurrence rules.&lt;br&gt;
Once the event is successfully created, an event ID will be returned as the unique identifier of the event. You can use this ID to update or delete the specified event later.&lt;br&gt;
Currently, there are two ways to create events:&lt;br&gt;
Method 1: Create events through the addEvent() or addEvents() interface under the calendar account. The addEvent() interface is used to create a single event, while addEvents() can create multiple events in batches. Here is an example of creating a single event:&lt;br&gt;
Method 2: After obtaining the calendar manager object, use the editEvent() interface to create a single event. When calling this interface, it will jump to the event creation page, where you can complete the event creation through relevant operations. Note that editEvent() does not support custom periodic event creation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Index.ets
let eventId : number | undefined = undefined;
const date = new Date();
const event: calendarManager.Event = {
  title: 'title',

  type: calendarManager.EventType.NORMAL,
  startTime: date.getTime(),
  endTime: date.getTime() + 60 * 60 * 1000,
  reminderTime: [10],
  recurrenceRule: {
    recurrenceFrequency: calendarManager.RecurrenceFrequency.DAILY,

    count: 100,

    interval: 2,

    expire: date.getTime() + 60 * 60 * 1000 * 3,
    excludedDates: [date.getTime() + 60 * 60 * 1000 * 2]
  },
  service: {
    type: calendarManager.ServiceType.TRIP,

    uri: 'xxx://xxx.xxx.com/xxx',
    description: ''
  }

};
calendar.addEvent(event).then((data: number) =&amp;gt; {
  console.info(`Succeeded in adding event, id -&amp;gt; ${data}`);
  eventId = data;
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to addEvent. Code: ${err.code}, message: ${err.message}`);
});
 const eventInfo: calendarManager.Event = {
  title: 'title',
  type: calendarManager.EventType.NORMAL,
  startTime: date.getTime(),
  endTime: date.getTime() + 60 * 60 * 1000
};
calendarMgr?.editEvent(eventInfo).then((id: number): void =&amp;gt; {
  console.info(`create Event id = ${id}`);
  eventId = id;
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to create Event. Code: ${err.code}, message: ${err.message}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6、Update the specified schedule according to the schedule ID and modify the relevant information of the schedule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Index.ets
const updateEvent: calendarManager.Event = {
  title: 'updateTitle',
  description: 'updateEventTest',
  type: calendarManager.EventType.NORMAL,
  id: eventId,
  startTime: date.getTime(),
  endTime: date.getTime() + 60 * 60 * 1000
};
calendar.updateEvent(updateEvent).then(() =&amp;gt; {
  console.info(`Succeeded in updating event`);
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to update event. Code: ${err.code}, message: ${err.message}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7、Query all schedules under the current calendar account. Due to data privacy and security considerations, apps with permission controls cannot access schedule information created by others. Different query results are returned based on different query conditions and fields.&lt;br&gt;
When there are no query conditions or fields, all schedules under the specified calendar account can be queried.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;calendar.getEvents().then((data: calendarManager.Event[]) =&amp;gt; {
  console.info(`Succeeded in getting events, data -&amp;gt; ${JSON.stringify(data)}`);
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to get events. Code: ${err.code}, message: ${err.message}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also supports querying schedules based on search criteria such as schedule ID, schedule start and end times, and schedule title.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const filterId = calendarManager.EventFilter.filterById([eventId]);
calendar.getEvents(filterId).then((data: calendarManager.Event[]) =&amp;gt; {
  console.info(`Succeeded in getting events, data -&amp;gt; ${JSON.stringify(data)}`);
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to get events. Code: ${err.code}, message: ${err.message}`);
});

const filterTitle = calendarManager.EventFilter.filterByTitle('update');
calendar.getEvents(filterTitle).then((data: calendarManager.Event[]) =&amp;gt; {
  console.info(`Succeeded in getting events, data -&amp;gt; ${JSON.stringify(data)}`);
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to get events. Code: ${err.code}, message: ${err.message}`);
});

const filterTime = calendarManager.EventFilter.filterByTime(1686931200000, 1687017600000);
calendar.getEvents(filterTime).then((data: calendarManager.Event[]) =&amp;gt; {
  console.info(`Succeeded in getting events filter by time, data -&amp;gt; ${JSON.stringify(data)}`);
}).catch((err: BusinessError) =&amp;gt; {
  console.error(`Failed to filter by time. Code: ${err.code}, message: ${err.message}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8、Delete a specified schedule by its schedule ID. You can delete a single schedule using the deleteEvent() interface or batch delete specified schedules using the deleteEvents() interface. Here is an example of deleting a single specified schedule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Index.ets
calendar.deleteEvent(eventId).then(() =&amp;gt; {
   console.info("Succeeded in deleting event");
 }).catch((err: BusinessError) =&amp;gt; {
   console.error(`Failed to delete event. Code: ${err.code}, message: ${err.message}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>HarmonyOS Next — Date and Calendar Components</title>
      <dc:creator>Rory-lhj</dc:creator>
      <pubDate>Wed, 21 May 2025 12:45:08 +0000</pubDate>
      <link>https://dev.to/rorylhj/harmonyos-next-date-and-calendar-components-4eei</link>
      <guid>https://dev.to/rorylhj/harmonyos-next-date-and-calendar-components-4eei</guid>
      <description>&lt;p&gt;In HarmonyOS application development, date and calendar components are an indispensable part of user interaction. The HarmonyOS system provides rich components and interfaces to meet developers’ needs for date and calendar functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Core Functions of Date and Calendar Components&lt;/strong&gt;&lt;br&gt;
The HarmonyOS system offers multiple date and calendar-related components, supporting the following functions:&lt;/p&gt;

&lt;p&gt;Date Selection: Users can select specific dates.&lt;br&gt;
Time Selection: Users can select specific times (hours and minutes).&lt;br&gt;
Calendar View: Displays a calendar interface, supporting operations such as month switching and date clicking.&lt;br&gt;
Internationalization Support: Supports date display in multiple languages and regional formats.&lt;br&gt;
&lt;strong&gt;2. Common Date and Calendar Components&lt;/strong&gt;&lt;br&gt;
(1) DatePicker Component&lt;br&gt;
Function: Used for date selection.&lt;br&gt;
Application Scenarios: Birthday selection, date booking, etc.&lt;br&gt;
Key Attributes:&lt;br&gt;
selected: The currently selected date.&lt;br&gt;
start and end: The range of date selection.&lt;br&gt;
onDateChange: Callback event when the date changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entry
@Component
struct Index {
    @State selectedDate: Date = new Date();

    build() {
        Column() {
            DatePicker({
                selected: this.selectedDate,
                start: new Date('2020-01-01'),
                end: new Date('2030-12-31')
            }).onDateChange((value: Date) =&amp;gt; {
                this.selectedDate = value;
                console.info('Selected date: ' + this.selectedDate.toString());
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(2) TimePicker Component&lt;/p&gt;

&lt;p&gt;Function: Used for time selection.&lt;br&gt;
Application Scenarios: Setting alarms, scheduling appointments, etc.&lt;br&gt;
Key Attributes:&lt;br&gt;
selected: The currently selected time.&lt;br&gt;
useMilitaryTime: Whether to use 24-hour format.&lt;br&gt;
onChange: Callback event when the time changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entry
@Component
struct Index {
    @State selectedTime: Date = new Date();

    build() {
        Column() {
            TimePicker({
                selected: this.selectedTime,
                useMilitaryTime: false
            }).onChange((value: TimePickerResult) =&amp;gt; {
                this.selectedTime.setHours(value.hour, value.minute);
                console.info('Selected time: ' + this.selectedTime.toString());
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(3) Calendar View Component&lt;/p&gt;

&lt;p&gt;Function: Displays a complete calendar interface, supporting month switching and date clicking.&lt;br&gt;
Implementation Methods:&lt;br&gt;
Implement the calendar view through custom components.&lt;br&gt;
Quickly integrate calendar functions using third-party open-source libraries (such as CalendarView).&lt;br&gt;
Key Functions:&lt;br&gt;
Display dates of the current month.&lt;br&gt;
Support switching to the previous month and the next month.&lt;br&gt;
Trigger events when dates are clicked.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Custom Calendar Components
If the system-provided components cannot meet requirements, developers can customize calendar components. The following are the key steps for customizing calendar components:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Designing the Calendar Layout&lt;br&gt;
Use the Grid or GridItem component to build the grid layout of the calendar.&lt;br&gt;
Each grid item represents a day, displaying the date and status.&lt;br&gt;
Handling Date Logic&lt;br&gt;
Dynamically generate date data based on the current month.&lt;br&gt;
Calculate which day of the week the first day of each month falls on and the number of days in each month.&lt;br&gt;
Adding Interaction Functions&lt;br&gt;
Trigger events when dates are clicked, such as displaying details or navigating to other pages.&lt;br&gt;
Support month switching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entry
@Component
struct CustomCalendar {
    @State currentDate: Date = new Date();

    build() {
        Column() {

            Text(`${this.currentDate.getFullYear()}${this.currentDate.getMonth() + 1}`)
                .fontSize(20)
                .margin({ bottom: 10 });


            Row() {
                ['7', '1', '2', '3', '4', '5', '6'].forEach(day =&amp;gt; {
                    Text(day).width('14%').textAlign(TextAlign.Center);
                });
            }.margin({ bottom: 5 });

            Grid({ columns: 7, rows: 6 }) {

                for (let i = 0; i &amp;lt; 42; i++) {
                    let date = this.getDateForIndex(i);
                    GridItem() {
                        if (date) {
                            Text(date.getDate().toString())
                                .width('100%')
                                .height('100%')
                                .textAlign(TextAlign.Center)
                                .onClick(() =&amp;gt; {
                                    console.info('Selected date: ' + date.toString());
                                });
                        }
                    };
                }
            }
        }
    }


    getDateForIndex(index: number): Date | null {
        let firstDayOfMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1);
        let dayOfWeek = firstDayOfMonth.getDay();
        let dateIndex = index - dayOfWeek + 1;

        if (dateIndex &amp;lt; 1 || dateIndex &amp;gt; this.getDaysInMonth()) {
            return null; 
        }

        return new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), dateIndex);
    }


    getDaysInMonth(): number {
        return new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 0).getDate();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
