倉頡編程語言青少年基礎教程:數組類型

倉頡編程語言青少年基礎教程:數組類型

數組本質上是有序、同類型數據的集合容器,其核心作用是高效組織、訪問和處理批量數據,同時結合語言特性,為開發者提供簡潔、高性能的數據管理方式。例如:

main() {
? ? let v1: Array<String> = ["a1", "a2", "a3"] // 使用 Array<String>
? ? println(v1[0]) // 成功輸出 a1
}

在倉頡語言中,“數組” 相關的類型主要包括 Array、VArray 和 ArrayList 三種,它們雖名稱或特性不同,但都用于組織有序的元素集合,只是在可變性、存儲方式和適用場景上有顯著差異。

三種類型的核心區別與選擇

類型

長度特性

類型性質

核心能力

整體拷貝成本

適用場景

Array<T>

固定

引用類型(結構體包裝)

不可增刪,可修改元素

僅復制引用

元素數量固定的場景

VArray<T,$N>

固定

值類型

不可增刪

按字節全復制

需減少堆內存、元素類型簡單場景

ArrayList<T>

動態

引用類型

可增刪改,支持擴容

僅復制引用

元素數量動態變化的場景

引用類型的數組Array

Array<T> ,其中T 表示 Array 的元素類型。引用類型(對象在堆上),放 同一種類型 T 的元素,順序固定,長度 創建后就不可變。用來構造單一元素類型,有序序列的數據。
可以輕松使用字面量來初始化一個 Array,只需要使用方括號將逗號分隔的值列表括起來即可。如:
let numbers: Array<Int64> = [1, 2, 3, 4]
// 也可省類型:let numbers = [1, 2, 3, 4]
也可以使用構造函數的方式構造一個指定元素類型的 Array。其中,repeat 屬于 Array 構造函數中的一個命名參數。如:
// 1. 指定長度 + 重復值
let zeros = Array<Int64>(10, repeat: 0) ? // [0,0,0,0,0,0,0,0,0,0]
// 2. 長度 + ?lambda 表達式
let squares = Array<Int64>(5, { i => i * i }) ?// [0,1,4,9,16]
需要注意的是,當通過 repeat 指定的初始值初始化 Array 時,該構造函數不會拷貝 repeat,如果 repeat 是一個引用類型,構造后數組的每一個元素都將指向相同的引用。如:
let d = Array<Int64>(3, repeat: 0) // repeat創建一個元素類型為Int64,長度為3,初始化為0

元素類型相同的 Array之間,可以互相賦值。元素類型不相同的 Array 是不相同的類型,不可以互相賦值。如:
let a: Array<Int64> ?= [1, 2]
let b: Array<UInt8> ?= [1, 2]
// a = b ?// ? 類型不匹配

可以通過索引(從 0 開始)訪問如 numbers[0]。例如:
let arr = [0,1,2,3,4,5]
println("第一個元素是${arr[0]}") ?//第一個元素是0
arr [0] = 3
println("現在第一個元素是${arr[0]}") //現在第一個元素是3

可以使用 for-in 循環遍歷 Array 的所有元素。如:
let numbers: Array<Int64> = [1, 2, 3, 4, 5]
for (i in numbers) { println(i) }
遍歷元素常規寫法:
for (i in 0.. numbers.size) {
? ? println("v[${i}] = ${v[i]}")
}

簡單而完整的示例:

main() {let v: Array<Int64> = [10, 20, 30, 40]// for-in 循環遍歷for (i in v) {println(i)}// 遍歷元素,常規寫法for (i in 0..v.size) {println("v[${i}] = ${v[i]}")}
}

編譯運行截圖:

可以使用 size 屬性獲得 Array 包含的元素個數。如:
main() {
? ? let arr = [0, 1, 2]
? ? println("數組的大小為 ${arr.size}") ?// 數組的大小為 3
}

綜合示例

main() {// Array示例:存儲固定的3個月份let months: Array<String> = ["Jan", "Feb", "Mar"]println(months[1])  // 輸出:Janmonths[1] = "February"  // 允許修改元素println(months[1])  // 輸出:Janlet d = Array<Int64>(3, repeat: 0) // repeat創建一個元素類型為Int64,長度為3,所有元素初始化為0的數組 for (n in d) { println(n)} var a: Array<Int64> = [0, 0, 0, 0] // 元素類型為Int64的數組var b: Array<String> = ["a1", "a2", "a3"] // 元素類型為String的數組var c: Array<String> = b  //元素類型相同的 Array之間可以互相賦值println("a的元素個數${a.size}")//元素個數//for-in 遍歷for (n in c) { println(n)}//編譯器會根據上下文自動推斷 Array 字面量的類型。var x: Array<String> =[] //創建一個元素類型為String的空數組x = ["bb1","bb2"]for (n in x) { println(n)}let y =[1,2,3] //創建元素類型為Int64的數組,包含元素1,2,3for (n in y) { println(n)}// x = y // 類型不匹配   
}

輸出:

Feb
February ? ?
0
0
0
a的元素個數4
a1
a2
a3
bb1
bb2
1
2
3

注意,Array 是一種長度不變的 Collection(集合) 類型,因此 Array 沒有提供添加和刪除元素的成員函數

注意,Array 是一種長度不變的 Collection(集合) 類型,因此 Array 沒有提供添加和刪除元素的成員函數

數組切片(返回新 Array)

從 數組 numbers 中截取(切片)出下標 1 到下標 3(左閉右開區間)的所有元素,組成一個新的 Array,然后把這個新數組賦值給常量 slice。

示例:

main() {let numbers: Array<Int64> = [10, 99, 3, 7]let slice = numbers[1..3]  // [99, 3] for (n in slice) { println(n)}
}

編譯運行截圖:

值類型的數組VArray

VArray<T, $N>,不能省略 <T, $N>,其中 T 表示該值類型數組的元素類型(如Int64Float32Bool?等【注】),$N 是一個固定的語法。通過 $ 加上一個 Int64 類型的數值字面量表示這個值類型數組的長度(?$?開頭后接數字)。

【注】:由于運行時后端限制,當前 VArray<T, $N> 的元素類型 T 或 T 的成員不能包含引用類型(class 、 Array 、String等)、枚舉類型、Lambda 表達式(CFunc 除外)以及未實例化的泛型類型。如:let v1: VArray<String, $3> = ["a1", "a2", "a3"] 是錯誤的——String 做不了 VArray 元素。


VArray 可以由一個數組的字面量來進行初始化。如:
let rgb: VArray<UInt8, $3> = [255, 128, 0]
也可以用構造函數進行初始化。其中,repeat 屬于 Array 構造函數中的一個命名參數。如:
let c = VArray<Int64, $5>(repeat: 0) ?// 生成 [0, 0, 0, 0, 0](5 個 0)。
let b = VArray<Int64, $5>({ i => i }) // lambda 表達式,生成 [0, 1, 2, 3, 4]。

用下標[] 操作符訪問和修改元素:用 [] 加索引(索引必須是整數,從 0 開始),例如:
var a: VArray<Int64, $3> = [1, 2, 3]
let second = a[1] ?// 取第2個元素(值為2)
a[2] = 4 ? ? ? ? ? // 修改第3個元素,現在數組是 [1, 2, 4]

用 size 獲取 VArray 長度。例如:
var a: VArray<Int64, $3> = [1, 2, 3]
let s = a.size // 3

VArray<T, $N> 和 Array<T> 作為倉頡中兩種固定長度的數組類型,基礎操作有一定相似性,但也有不同,如遍歷元素,目前版本(Cangjie語言首個LTS版本1.0.0)的 VArray 不支持 for-in遍歷元素,可用常規寫法:

main() {let v: VArray<Int64,$4> = [10, 20, 30, 40]// // 不支持for-in 循環遍歷// for (i in v) {//     println(i)// }// 遍歷元素,常規寫法for (i in 0..v.size) {println("v[${i}] = ${v[i]}")}
}

輸出:

v[0] = 10
v[1] = 20
v[2] = 30
v[3] = 40

與頻繁使用引用類型 Array 相比,使用值類型 VArray 可以減少堆上內存分配和垃圾回收的壓力。但是需要注意的是,由于值類型本身在傳遞和賦值時的拷貝,會產生額外的性能開銷,因此建議不要在性能敏感場景使用較大長度的 VArray。

【——如何理解倉頡編程語言官方文檔這句話?

VArray 和 Array 各有性能優劣,需要根據場景選擇 —— 前者能減輕內存管理壓力,但拷貝成本高;后者傳遞成本低,但會增加內存回收負擔。

1. 為什么 VArray 能 “減少堆上內存分配和垃圾回收的壓力”?

內存存儲位置不同:

引用類型的 Array 數據通常存在“堆”里,每次創建 Array 都要在堆里申請一塊空間;而堆里的空間不會自動釋放,需要 “垃圾回收器”(Garbage Collector)定期來清理不用的空間。如果頻繁創建 Array,堆里會堆積大量臨時空間,垃圾回收器就需要頻繁工作(壓力大),甚至可能影響程序運行流暢度。

值類型的 VArray 數據通常存在“棧”里,棧的空間會隨著變量的生命周期自動釋放(比如函數執行完,棧上的 VArray 就自動消失),不需要垃圾回收器操心。因此,用 VArray 可以減少堆的使用,自然就減輕了垃圾回收的壓力。

2. 為什么“不要在性能敏感場景使用較大長度的 VArray”?

值類型的“拷貝成本”問題:

值類型的特點是“賦值或傳遞時會完整拷貝數據”。比如一個長度為 1000 的 VArray,每次把它傳給函數、或者賦值給另一個變量時,都要復制 1000 個元素(相當于把小盒子里的東西全倒出來,再一個個裝進新盒子)。

如果 VArray 很小(比如長度 3),拷貝成本可以忽略;但如果是大長度(比如長度 10000),每次拷貝都會消耗大量時間和內存帶寬。在“性能敏感場景”比如游戲的幀循環、高頻數據處理)中,這種頻繁的大拷貝會明顯拖慢速度,反而不如用 Array(引用類型傳遞時只拷貝一個“地址”成本極低)。

總結:是 “內存管理壓力” 和 “拷貝成本” 的權衡

小長度數組:用 VArray 更合適 —— 既減少堆內存和垃圾回收的麻煩,拷貝成本又低。

大長度數組:尤其在頻繁傳遞 / 賦值的性能敏感場景,用 Array 更合適 —— 雖然有堆內存和垃圾回收的壓力,但傳遞成本低,避免了大拷貝的性能損耗。

值類型的特點是 “賦值或傳遞時會完整拷貝數據”,引用類型的特點:賦值或傳遞時通常不會拷貝數據本身,而是拷貝 “引用”(即數據的內存地址)。這意味著多個引用類型變量可以共享同一份數據,修改其中一個變量指向的數據,會影響所有指向該數據的變量。

“通常不會拷貝”≠“永遠不會拷貝”。

倉頡的 Array、String 等引用類型在寫時復制(COW :copy-on-write) 優化下,第一次真正修改時仍可能觸發一次惰性拷貝,從而把共享拆成兩份數據。

因此:

? 日常代碼層面:

“賦值/傳參只拷引用,修改共享數據會互相可見”這句話成立。

? 底層實現細節:

如果對象內部做 COW,則真實的物理拷貝會延遲到第一次寫操作。】

ArrayList 類型

這個是動態數組(也叫順序表)。使用 ArrayList 類型需要導入 collection 包:

import std.collection.*

【ArrayList相關官方文檔:https://cangjie-lang.cn/docs?url=%2F1.0.0%2Fuser_manual%2Fsource_zh_cn%2Fcollections%2Fcollection_arraylist.html 】

Array和ArrayList的異同點
Array:如果不需要增加和刪除元素,但需要修改元素,就應該使用它。
ArrayList:如果需要頻繁對元素增刪查改,就應該使用它。相比 Array,ArrayList 既可以原地修改元素,也可以原地增加和刪除元素。
使用 ArrayList 類型需要導入 collection 包:import std.collection.*
ArrayList 的可變性是一個非常有用的特征,可以讓同一個 ArrayList 實例的所有引用都共享同樣的元素,并且對它們統一進行修改。
不同元素類型的ArrayList是不同類型,不能互相賦值。如:
var intList: ArrayList<Int64> = ...
var strList: ArrayList<String> = ...
strList = intList ?// 不合法報錯,類型不匹配

倉頡提供了多種構造ArrayList的方式
// 1. 創建空的ArrayList
let emptyList = ArrayList<String>()

// 2. 指定初始容量創建
let preAllocated = ArrayList<String>(100) ?// 預分配100個元素的空間

// 3. 從數組初始化
let fromArray = ArrayList<Int64>([0, 1, 2])

// 4. 從其他Collection初始化
let copyList = ArrayList<Int64>(fromArray)

// 5. 通過函數規則初始化
let funcInit = ArrayList<String>(2, {x: Int64 => x.toString()})

ArrayList 的基本用法
1.使用size屬性獲取大小:
let list = ArrayList<Int64>([0, 1, 2])
println("list大小: ${list.size}")
2.訪問單個元素:使用下標語法。示例:

main(){let list = ArrayList<Int64>([0, 1, 2])let first = list[0]      // 正確,訪問第一個元素let last = list[list.size - 1]  // 正確,訪問最后一個元素  println(first)  // 0println(last)   // 2
}

3. 遍歷元素:使用for-in循環。示例:

main(){let list = ArrayList<Int64>([0, 1, 2])for (i in list) {println("元素: ${i}")}
}

4.范圍訪問:支持Range語法(與 Array 相同)。示例:

main() {// 創建一個包含 0-9 的 ArrayListlet list = ArrayList<Int64>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])// 1. 獲取從索引 2 到 5(包含 2,不包含 5)的元素let sub1 = list[2..5]println("子序列 [2..5]: ${sub1}")  // 輸出: [2, 3, 4]// 2. 獲取從索引 0 到 3(包含 0,不包含 3)的元素let sub2 = list[0..3]println("子序列 [0..3]: ${sub2}")  // 輸出: [0, 1, 2]// 3. 獲取從索引 6 到末尾的元素let sub3 = list[6..list.size]println("子序列 [6..end]: ${sub3}")  // 輸出: [6, 7, 8, 9]   
}

重要特性

1.引用類型特性:

??? 賦值時不拷貝數據,僅傳遞引用

??? 所有引用共享同一數據,一處修改處處可見

示例:

main() {let list1 = ArrayList<Int64>([0, 1, 2])let list2 = list1list2[0] = 3// list1 和 list2 現在都為 [3, 1, 2] for (i in list1) {println("list1元素: ${i}")}for (i in list2) {println("list2元素: ${i}")}    
}

2.ArrayList自動擴容機制:

??? 當元素數量超過當前容量時,會自動分配更大的內存。擴容操作有性能成本。

??? 可通過初始化時指定容量或使用reserve()方法預分配空間

示例:

import std.collection.*
import std.time.*  // 用于計時MonoTime.now()main() {// 創建未指定初始容量的空ArrayList(初始容量較小,假設為10)let list = ArrayList<Int64>(10)let start = MonoTime.now()  // 記錄開始時間// 循環添加10000個元素,會多次觸發自動擴容for (i in 0..10000) {list.add(i)}let end = MonoTime.now()  // 記錄結束時間println("未預分配容量時,添加10000個元素耗時: ${end - start}毫秒")
}

說明:

每次擴容都需要申請新內存并復制現有元素,多次擴容會累積性能成本,導致總耗時較長。

也可以使用reserve()方法預分配。示例:

import std.collection.*
import std.time.*  // 用于計時,MonoTime.now()main() {let list = ArrayList<Int64>(10)list.reserve(10000)  // 手動預分配足夠容量let start = MonoTime.now()for (i in 0..10000) {list.add(i)}let end = MonoTime.now()println("reserve預分配容量時,添加10000個元素耗時: ${end - start}毫秒")
}

運行對比,后面的優化方案的耗時會顯著低于“無預分配”的場景。

最后給出一個ArrayList綜合示例

import std.collection.*main() {// 1. 創建let list = ArrayList<String>()      // 空列表// let mut list = ArrayList<String>(100) // 預分配 100 容量// let list = ArrayList<Int64>([0, 1, 2]) // 用 Collection 初始化// 2. 增list.add("Apple")list.add("Banana")list.add(all: ["Orange", "Pear"])       // 批量追加  [Apple Banana Orange Pear]for (item in list) {println(item)}// 3. 插list.add("Grape", at: 1)                // 索引 1 處插入// 4. 刪list.remove(at: 2)                      // 刪除索引 2 的元素// 5. 改list[0] = "Pineapple"// 6. 查println("size = ${list.size}")          // size = 3println("first = ${list[0]}")           // first = Pineapple// 7. 遍歷 [Pineapple Grape Orange Pear]for (item in list) {println(item)}    
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/922152.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922152.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922152.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++微基礎藍橋杯之旅9.9-9.12

這里主要還是強制類型轉換的使用//打印字符ASCII碼值 //輸入一個除空格以外的可見字符 //輸出其ASCII值--十進制整數 #include <iostream> using namespace std;int main() {char ch;cin >> ch;//字符cout << (int)ch << endl; return 0; }//打印字符…

邏輯漏洞(上)- 突破功能限制漏洞、用戶信息泄露(邏輯漏洞入門)

漏洞介紹&#xff1a; 在網絡攻防實戰中&#xff0c;常會遇到各種前端限制&#xff0c;繞過限制的方法大多是改包或者修改前端代碼來實現的。 漏洞環境&#xff1a;docker docker-compose up -d 啟動環境后&#xff1a;訪問 http://127.0.0.1:8983/web/# 發現查詢按鈕是無法使用…

tsv文件簡介

初步了解tsv文件在很多 OCR&#xff08;光學字符識別&#xff09;項目中&#xff0c;.tsv文件是標準的訓練數據標注文件&#xff0c;主要用于存儲 “圖像路徑 - 對應文本標簽” 的映射關系&#xff0c;同時可能包含圖像尺寸、文本長度等輔助信息&#xff0c;方便模型讀取訓練數…

apache poi 導出復雜的excel表格

如何導出復雜的excel 表格 如圖表格&#xff0c;存在行和列的合并&#xff0c;邊框&#xff0c;樣式&#xff0c;顏色等。依賴<!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><arti…

下載 Eclipse Temurin 的 OpenJDK 提示 “無法訪問此網站 github.com 的響應時間過長”

打開 Eclipse Temurin 的 OpenJDK 的官網下載地址&#xff1a; https://adoptium.net/zh-CN/temurin/releases 問 deepseek&#xff1a; 國內網絡&#xff0c;打不開github.com網頁&#xff0c;提示github.com 的響應時間過長。 國內無法訪問 GitHub 或訪問緩慢&#xff0c;通…

C/C++類型轉換

C/C類型轉換 1. C類型轉換 C 語言中的類型轉換主要分為兩種&#xff1a;隱式類型轉換 (Implicit Conversion) - 由編譯器自動完成。顯式類型轉換 (Explicit Conversion) - 由程序員強制指定&#xff0c;也稱為強制類型轉換。1.2 隱式類型轉換 編譯器在編譯時自動進行的轉換&…

【Java】Windows切換Java8和Java11

現在有些項目要升級到Java17, 所以需要切換不同的java版本。 如何安裝Java8 由于已經安裝了jJava8, 之前的安裝文章&#xff1a;【Java】jdk8安裝——英文版 如何安裝Java17 Java17下載地址 https://www.oracle.com/java/technologies/downloads/#java17-windows 下載到電…

SQLite 數據庫核心知識與 C 語言編程

一、數據庫基礎概念1.1 數據庫分類根據規模和應用場景&#xff0c;數據庫可分為以下幾類&#xff1a;大型數據庫&#xff1a;Oracle&#xff08;適用于企業級高并發、大容量場景&#xff09;中型數據庫&#xff1a;MySQL、MSSQL&#xff08;適用于中小型系統、Web 應用&#xf…

Netty 調優篇:實戰配置、性能監控與常見坑

&#x1f680; Netty 調優篇&#xff1a;實戰配置、性能監控與常見坑前面我們已經深入了 Netty 的 線程模型、Pipeline、EventLoop、內存池、零拷貝和背壓機制。 但在實際工作中&#xff0c;很多人踩坑的地方不是“源碼沒看懂”&#xff0c;而是 調優沒做好。 今天我們就從三個…

Linux Node.js 安裝及環境配置詳細教程

如果您喜歡此文章&#xff0c;請收藏、點贊、評論&#xff0c;謝謝&#xff0c;祝您快樂每一天。 一、Node.js是什么 Node.js是一個基于Chrome V8引擎的[JavaScript運行環境]。 Node.js使用了一個事件驅動、非阻塞式I/O 的模型。 Node.js是一個讓JavaScript運行在服務端的開…

呼叫中心系統IVR流程設計的心理學

呼叫中心的 IVR&#xff08;交互式語音應答&#xff09;系統看似是 “機器與用戶的對話”&#xff0c;實則暗藏對用戶心理的精準把握。其設計需圍繞降低焦慮、提升效率、強化信任三大核心目標&#xff0c;背后依托認知心理學、行為心理學、情感心理學等理論支撐。一、認知負荷理…

一些開源或免費的網絡管理工具

整理開源及免費網絡管理工具推薦,涵蓋監控、配置、安全、流量分析等場景,適用于不同規模的網絡環境: ?一、網絡監控與性能分析? 1. ?Zabbix? ?特點?:企業級監控方案,支持SNMP、IPMI、JMX等多種協議,提供實時儀表盤、告警通知和自動化發現功能。 ?適用場景?:服…

谷粒商城項目-P16快速開發-人人開源搭建后臺管理系統

1.對腳手架工程進行改造 此項目選用的腳手架工程是人人開源 地址&#xff1a;人人開源 選擇的是下圖標紅的renren-fast作為后端&#xff0c;renren-fast-vue作為前端 克隆上述兩個項目 2.后端改造 2.1將renrenfast項目的git文件夾刪除后&#xff0c;拖進后端代碼文件夾中 2…

V少JS基礎班之第八彈:this

文章目錄一、 前言二、本節涉及知識點三、重點內容1、從新的角度認識this2、this是函數的參數3、this的值4、函數的調用1- 裸函數調用2- 函數作為構造函數調用3- 函數作為對象的方法調用4- 函數顯示調用5- 箭頭函數一、 前言 第八彈內容是this。this相對來說難度不大&#xff…

《堆的詳解:結構、操作及堆排序算法》

目錄 一.堆的概念與結構 1.1 堆的概念 1.2 堆性質&#xff1a; 1.3 堆的結構定義 二.堆的初始化和銷毀 2.1 堆的初始化&#xff1a; 2.2 堆的銷毀&#xff1a; 三.堆的插入數據(含向上調整算法的實現) 3.1 插入邏輯 3.2 插入函數 3.3 向上調整算法 三. 堆的刪除數…

深入解析 Kubernetes 中的 Service 資源:為應用提供穩定的網絡訪問

什么是 Kubernetes 中的 Service&#xff1f; 在現代微服務架構中&#xff0c;服務之間的通信和負載均衡是至關重要的。尤其是在 Kubernetes 環境中&#xff0c;由于 Pod 是動態創建和銷毀的&#xff0c;如何為一組 Pod 提供穩定的訪問入口&#xff0c;成為了架構設計中的一個關…

使用Samba網絡磁盤作為MacOS時間機器的遠程備份磁盤

最近考慮MacOS系統升級&#xff0c;所以需要做磁盤備份&#xff0c;MacOS里有個備份磁盤很方便的工具&#xff1a;時間機器&#xff0c;可以自動定期備份磁盤&#xff0c;但是一般需要一個大點的移動硬盤插在macbook上選擇其為備份磁盤&#xff0c;可惜我并沒有移動硬盤&#x…

智能頭盔實時監控系統設計與實現

智能頭盔實時監控系統設計與實現 源碼 https://gitee.com/intostars/csdn-demo/tree/master/src/views/smartHelmet 預覽 一、功能概述 智能頭盔實時監控系統是基于Vue 3和TypeScript開發的一套用于遠程監控和控制智能頭盔設備的前端應用模塊。該系統通過WebSocket與后端服務…

Docker 學習筆記(八):容器運行時工具實踐及 OpenStack 部署基礎

容器管理工具Containerd nerdctl 實踐 nerdctl管理存儲 nerdctl命令創建容器的時候&#xff0c;可以使用-v選項將本地目錄掛載給容器實現數據持久化 示例&#xff1a; [rootlocalhost ~]# mkdir /data [rootlocalhost ~]# nerdctl run -d -v /data:/data busybox -- sleep infi…

Unity鍵盤控制角色運動

以下是一個完整的Unity角色移動和跳躍腳本,支持WASD或方向鍵移動: 使用說明 確保組件設置正確: 確保您的游戲對象有一個CharacterController組件 如果沒有,可以通過菜單 "Component -> Physics -> Character Controller" 添加 相機設置: 確保場景中有一…