TypeScript 基礎介紹(二)

引言:從基礎到結構化類型

? ? ? ? 在《TypeScript 基礎介紹(一)》TypeScript基礎介紹(一)-CSDN博客中,我們探討了 TypeScript 的類型系統基礎、聯合類型、類型斷言和類型守衛等核心特性。這些內容解決了 JavaScript 在類型檢查和代碼可讀性方面的基礎問題。然而,隨著應用規模增長,我們需要更強大的工具來描述復雜對象結構、復用類型定義并實現類型安全的代碼復用。本文 fly 將繼續深入 TypeScript 的結構化類型系統,包括接口、類型別名、函數類型、泛型及類與接口的結合,通過實戰案例展示如何構建健壯且可維護的類型系統。

目錄

引言:從基礎到結構化類型

六、接口:定義對象的結構契約

6.1 基礎接口定義與使用

6.2 接口的索引簽名:動態屬性名

6.3 接口繼承:復用與擴展類型

七、類型別名:創建自定義類型

7.1 基礎類型別名

7.2 對象類型別名

八、函數類型:精確描述函數簽名

8.1 函數類型表達式

8.2 接口定義函數類型

8.3 函數參數的高級類型

九、泛型:編寫可復用的類型安全代碼

9.1 泛型函數:適應多種類型

9.2 泛型約束:限制類型范圍

9.3 泛型接口與類

十、類與接口:面向對象編程的類型約束

10.1 類實現接口

10.2 類的類型繼承與接口實現結合

十一、交叉類型:組合多個類型

十二、類型別名 vs 接口:何時選擇哪種方式

12.1 核心區別對比

12.2 最佳實踐建議

結語


六、接口:定義對象的結構契約

? ? ? ? 接口(Interface)是 TypeScript 中描述對象形狀的核心工具,它定義了對象必須包含的屬性和方法,是實現代碼契約化設計的基礎。與基本類型不同,接口專注于描述復雜數據結構,確保不同部分的代碼遵循一致的數據格式。

6.1 基礎接口定義與使用

? ? ? ?接口通過interface關鍵字聲明,指定對象應包含的屬性名稱、類型及可選性:

// 定義用戶接口
interface User {id: number;          // 必選屬性name: string;        // 必選屬性age?: number;        // 可選屬性(使用?標記)readonly email: string; // 只讀屬性(初始化后不可修改)
}// 正確實現接口
const validUser: User = {id: 1,name: "Alice",email: "alice@example.com"
};// 錯誤示例:缺少必選屬性id
const invalidUser: User = {name: "Bob",email: "bob@example.com"// ? 類型 "{ name: string; email: string; }" 中缺少屬性 "id",但類型 "User" 中需要該屬性
};// 錯誤示例:修改只讀屬性
validUser.email = "new-email@example.com";
// ? 無法分配到 "email" ,因為它是只讀屬性

關鍵特性

  • 必選屬性:默認情況下,接口屬性為必填,實現時必須提供
  • 可選屬性:通過?標記,允許對象缺少該屬性(如age?: number
  • 只讀屬性:通過readonly關鍵字,確保屬性初始化后不可修改(運行時仍可通過索引修改,但編譯時會報錯)

6.2 接口的索引簽名:動態屬性名

? ? ? ? 當對象屬性名不確定但類型已知時,可使用索引簽名定義鍵值對的類型約束:

// 字符串索引簽名:鍵為string,值為number
interface NumberDictionary {[key: string]: number;length: number; // 允許,因為length是string類型鍵,值為number// name: string; // ? 錯誤,值類型必須為number
}// 數字索引簽名:鍵為number,值為string
interface StringArray {[index: number]: string;
}const fruits: StringArray = ["apple", "banana", "cherry"];
console.log(fruits[0]); // 輸出: "apple"(TypeScript推斷為string類型)

應用場景:處理 JSON 數據、配置對象等動態結構,同時保持類型安全。

6.3 接口繼承:復用與擴展類型

? ? ? ? 接口支持通過extends關鍵字繼承其他接口,實現類型復用和擴展:

// 基礎接口
interface Person {name: string;age: number;
}// 繼承Person并添加職業屬性
interface Employee extends Person {department: string;salary: number;
}// 實現繼承后的接口
const employee: Employee = {name: "John",age: 30,department: "Engineering",salary: 80000
};// 多繼承:同時繼承多個接口
interface Contact {phone: string;
}interface Staff extends Person, Contact {id: number;
}const staff: Staff = {name: "Jane",age: 28,phone: "123-456-7890",id: 1001
};

優勢:避免代碼重復,構建層次化的類型體系,符合開閉原則(對擴展開放,對修改封閉)。

七、類型別名:創建自定義類型

? ? ? ? 類型別名(Type Alias)通過type關鍵字為已有類型創建新名稱,支持基本類型、聯合類型、交叉類型等復雜場景,是定義復用類型的靈活工具。

7.1 基礎類型別名

? ? ? ? 為基本類型或聯合類型創建別名,提升代碼可讀性:

// 為基本類型創建別名
type Age = number;
type Name = string;// 為聯合類型創建別名
type Status = "active" | "inactive" | "pending";
type ID = string | number;// 使用類型別名
let userAge: Age = 25;
let userName: Name = "Alice";
let userStatus: Status = "active"; // 只能賦值指定的字符串字面量
let userId: ID = "user-123"; // 合法,string類型
userId = 456; // 合法,number類型// 錯誤示例:賦值不在聯合類型中的值
userStatus = "deleted"; 
// ? 類型 ""deleted"" 不能賦值給類型 "Status"

7.2 對象類型別名

? ? ? ? 與接口類似,類型別名可描述對象結構,但支持更復雜的組合:

// 對象類型別名
type Point = {x: number;y: number;z?: number; // 可選屬性
};// 聯合類型別名
type Shape = | { kind: "circle"; radius: number }| { kind: "square"; sideLength: number }| { kind: "triangle"; base: number; height: number };// 使用類型別名計算面積
function calculateArea(shape: Shape): number {switch (shape.kind) {case "circle":return Math.PI * shape.radius ** 2;case "square":return shape.sideLength ** 2;case "triangle":return (shape.base * shape.height) / 2;default://  exhaustive check( exhaustive:徹底的):確保覆蓋所有可能的類型const _exhaustiveCheck: never = shape;return _exhaustiveCheck;}
}// 示例調用
console.log(calculateArea({ kind: "circle", radius: 5 })); // 輸出: 78.5398...
console.log(calculateArea({ kind: "square", sideLength: 10 })); // 輸出: 100

關鍵特性:支持聯合類型、交叉類型等復雜組合,適合描述非對象類型(如基本類型、聯合類型)。

八、函數類型:精確描述函數簽名

? ? ? ? TypeScript 允許通過函數類型表達式接口定義函數的參數和返回值類型,確保函數調用的類型安全。

8.1 函數類型表達式

? ? ? ? 直接在函數變量或參數中定義類型:

// 定義函數類型:(參數1: 類型, 參數2: 類型) => 返回值類型
type AddFunction = (a: number, b: number) => number;// 使用函數類型
const add: AddFunction = (a, b) => a + b;
console.log(add(2, 3)); // 輸出: 5// 錯誤示例:參數類型不匹配
const subtract: AddFunction = (a: string, b: number) => a - b;
// ? 不能將類型 "(a: string, b: number) => number" 分配給類型 "AddFunction"// 函數作為參數時的類型
function calculate(operation: AddFunction, x: number, y: number): number {return operation(x, y);
}console.log(calculate(add, 10, 20)); // 輸出: 30

8.2 接口定義函數類型

? ? ? ? ?通過接口的調用簽名描述函數結構,適合需要擴展屬性的函數:

// 接口定義函數類型(調用簽名)
interface GreetFunction {(name: string, greeting?: string): string; // 函數參數和返回值defaultGreeting: string; // 函數額外屬性
}// 實現接口
const greet: GreetFunction = (name, greeting = greet.defaultGreeting) => {return `${greeting}, ${name}!`;
};
greet.defaultGreeting = "Hello";// 調用函數
console.log(greet("Alice")); // 輸出: "Hello, Alice!"
console.log(greet("Bob", "Hi")); // 輸出: "Hi, Bob!"

8.3 函數參數的高級類型

? ? ? ? 詳細講解函數參數的類型細節,包括可選參數、默認參數、剩余參數:

// 可選參數:使用?標記,必須放在必選參數之后
function logUser(name: string, age?: number): void {console.log(`Name: ${name}, Age: ${age ?? "Unknown"}`);
}
logUser("Alice"); // 輸出: "Name: Alice, Age: Unknown"// 默認參數:指定默認值,自動成為可選參數
function createUser(name: string, role: string = "user"): { name: string; role: string } {return { name, role };
}
console.log(createUser("Bob")); // 輸出: { name: "Bob", role: "user" }// 剩余參數:使用...收集多個參數為數組
function sum(...numbers: number[]): number {return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 輸出: 10

? ? ? ? ?最佳實踐:為所有公共函數添加完整的類型注解,特別是參數和返回值類型,提升代碼可讀性和重構安全性。

九、泛型:編寫可復用的類型安全代碼

? ? ? ? 泛型(Generics)是 TypeScript 實現類型復用的核心機制,允許在定義函數、接口或類時不指定具體類型,而在使用時動態指定,實現 "一次定義,多種類型復用"。

9.1 泛型函數:適應多種類型

? ? ? ? 定義一個可處理不同類型數據的函數,同時保持類型安全:

// 泛型函數:T是類型變量,代表傳入的類型
function identity<T>(arg: T): T {return arg; // 返回與輸入相同類型的值
}// 使用泛型函數(顯式指定類型)
const num: number = identity<number>(42);
const str: string = identity<string>("hello");// 類型推斷(推薦):TypeScript自動推斷T為傳入的類型
const bool = identity(true); // T被推斷為boolean類型// 泛型函數示例:獲取數組第一個元素
function getFirstElement<T>(array: T[]): T | undefined {return array[0];
}// 使用示例
const numbers = [1, 2, 3];
const firstNum = getFirstElement(numbers); // 推斷為number | undefined
console.log(firstNum); // 輸出: 1const strings = ["a", "b", "c"];
const firstStr = getFirstElement(strings); // 推斷為string | undefined

9.2 泛型約束:限制類型范圍

? ? ? ? 使用extends關鍵字約束泛型只能是特定類型或具有特定屬性:

// 泛型約束:T必須具有length屬性
interface Lengthwise {length: number;
}function logLength<T extends Lengthwise>(arg: T): T {console.log(`Length: ${arg.length}`);return arg;
}logLength("hello"); // 輸出: "Length: 5"(string有length屬性)
logLength([1, 2, 3]); // 輸出: "Length: 3"(數組有length屬性)
// logLength(42); // ? 錯誤,number沒有length屬性// 泛型約束:使用keyof獲取對象鍵的聯合類型
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {return obj[key];
}const user = { name: "Alice", age: 25 };
console.log(getProperty(user, "name")); // 輸出: "Alice"(類型為string)
console.log(getProperty(user, "age")); // 輸出: 25(類型為number)
// getProperty(user, "email"); // ? 錯誤,"email"不是user的鍵

9.3 泛型接口與類

? ? ? ? 將泛型應用于接口和類,創建可復用的類型組件:

// 泛型接口
interface Box<T> {value: T;getValue: () => T;
}// 實現泛型接口
const numberBox: Box<number> = {value: 100,getValue: () => numberBox.value
};const stringBox: Box<string> = {value: "TypeScript",getValue: () => stringBox.value
};// 泛型類
class Stack<T> {private items: T[] = [];push(item: T): void {this.items.push(item);}pop(): T | undefined {return this.items.pop();}
}// 使用泛型類
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 輸出: 2const stringStack = new Stack<string>();
stringStack.push("a");
stringStack.push("b");
console.log(stringStack.pop()); // 輸出: "b"

? ? ? ? 泛型的價值:在保持類型安全的同時,大幅提升代碼復用性,是開發通用庫和組件的基礎。

十、類與接口:面向對象編程的類型約束

? ? ? ? TypeScript 結合了面向對象編程和類型系統,允許通過接口約束類的實現,確保類遵循特定的結構。

10.1 類實現接口

? ? ? ? 使用implements關鍵字使類遵循接口定義的結構:

// 定義接口
interface Animal {name: string;makeSound(): void;
}// 類實現接口
class Dog implements Animal {name: string;constructor(name: string) {this.name = name;}makeSound(): void {console.log("Woof!");}// 類可以有接口之外的方法fetch(): void {console.log(`${this.name} is fetching the ball`);}
}// 實例化類
const dog = new Dog("Buddy");
dog.makeSound(); // 輸出: "Woof!"
dog.fetch(); // 輸出: "Buddy is fetching the ball"// 錯誤示例:未實現接口的方法
class Cat implements Animal {name: string;constructor(name: string) {this.name = name;}// ? 錯誤,Cat類缺少"makeSound"方法的實現
}

10.2 類的類型繼承與接口實現結合

? ? ? ? 類可以同時繼承另一個類并實現接口,實現代碼復用和接口約束的雙重目的:

// 基礎類
class Vehicle {speed: number;constructor(speed: number) {this.speed = speed;}move(): void {console.log(`Moving at ${this.speed} km/h`);}
}// 接口
interface Flyable {altitude: number;fly(): void;
}// 繼承類并實現接口
class Airplane extends Vehicle implements Flyable {altitude: number;constructor(speed: number, altitude: number) {super(speed); // 調用父類構造函數this.altitude = altitude;}// 重寫父類方法move(): void {console.log(`Flying at ${this.speed} km/h and ${this.altitude} m altitude`);}// 實現接口方法fly(): void {console.log("Taking off!");}
}// 使用類
const plane = new Airplane(900, 10000);
plane.fly(); // 輸出: "Taking off!"
plane.move(); // 輸出: "Flying at 900 km/h and 10000 m altitude"

十一、交叉類型:組合多個類型

? ? ? ? 交叉類型(Intersection Types)使用&符號將多個類型合并為一個,新類型包含所有類型的屬性和方法,適用于組合對象結構。

// 定義兩個接口
interface HasName {name: string;
}interface HasAge {age: number;
}// 交叉類型:同時包含HasName和HasAge的屬性
type Person = HasName & HasAge;// 使用交叉類型
const person: Person = {name: "Alice",age: 25
};// 交叉類型與聯合類型的區別
type A = { a: number } & { b: string }; // 必須同時有a和b
type B = { a: number } | { b: string }; // 可以有a或b或兩者都有// 復雜交叉類型示例
type WithId = { id: string };
type User = HasName & HasAge & WithId;const user: User = {id: "user-123",name: "Bob",age: 30
};

注意:交叉類型不適合基本類型組合(如string & number會得到never類型,因為沒有值同時是 string 和 number)。

十二、類型別名 vs 接口:何時選擇哪種方式

? ? ? ? 類型別名和接口都可用于定義對象結構,但在使用場景上有明確區別,選擇正確的工具能提升代碼清晰度和可維護性。

12.1 核心區別對比

特性類型別名(type)接口(interface)
定義范圍可描述任意類型(對象、聯合、基本類型等)主要用于描述對象結構和函數類型
擴展方式通過交叉類型(type A = B & { ... }通過繼承(interface A extends B
合并聲明不支持重復聲明合并支持重復聲明自動合并
計算屬性支持(如type Keys = keyof T支持,但語法更復雜

12.2 最佳實踐建議

  • 優先使用接口當:

    • 定義對象結構且需要繼承或被繼承
    • 需要自動合并聲明(如擴展第三方庫類型)
    • 描述類的公共 API(更符合面向對象思維)
  • 優先使用類型別名當:

    • 定義聯合類型、交叉類型或基本類型別名
    • 描述元組類型(如type Point = [number, number]
    • 需要使用計算屬性或條件類型
// 接口合并示例(接口特有)
interface Config {apiUrl: string;
}interface Config {timeout: number;
}// 自動合并為 { apiUrl: string; timeout: number }
const config: Config = {apiUrl: "https://api.example.com",timeout: 5000
};// 類型別名不支持合并
type Settings = { theme: string };
// type Settings = { layout: string }; // ? 錯誤,重復的標識符"Settings"

結語

? ? ? ? 本文深入探討了 TypeScript 的結構化類型特性,包括接口、類型別名、函數類型、泛型、類與接口的結合及交叉類型等核心概念。這些工具共同構成了 TypeScript 強大的類型系統,使開發者能夠構建類型安全、可維護且高度復用的代碼。

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

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

相關文章

【科研繪圖系列】R語言繪制線性相關性

文章目錄 介紹 加載R包 數據下載 導入數據 數據預處理 畫圖 系統信息 參考 介紹 【科研繪圖系列】R語言繪制線性相關性 加載R包 library(tidyverse) library(ggplot2) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2

FastAPI的請求-響應周期為何需要后臺任務分離?

url: /posts/c7b54d6b3b6b5041654e69e5610bf3b9/ title: FastAPI的請求-響應周期為何需要后臺任務分離? date: 2025-07-31T06:11:25+08:00 lastmod: 2025-07-31T06:11:25+08:00 author: cmdragon summary: FastAPI 的請求-響應周期遵循 ASGI 協議,類似于餐廳點餐流程。同步處…

多種錄音筆錄音芯片方案推薦

多種錄音筆錄音芯片方案推薦一、引言隨著信息技術的飛速發展&#xff0c;錄音筆作為一種重要的音頻記錄設備&#xff0c;在會議記錄、采訪、學習等眾多場景中得到廣泛應用。其核心的錄音芯片方案直接影響錄音質量、功能特性以及產品成本。唯創知音作為音頻芯片領域的知名廠商&a…

Linux系統編程Day2-- Linux常用操作

一、Linux 基本命令概覽以下是一些常用的Linux命令操作&#xff0c;后續我們會對其每個單獨如何使用進行講解。操作類型常用命令示例文件/目錄操作ls, cd, cp, mv, rm, mkdir, rmdir查看文件內容cat, less, more, head, tail查找操作find, grep, locate, which權限管理chmod, c…

cs336 assignment1 作業環境配置

代碼結構 所有的代碼寫到cs336_basics/* 下面&#xff0c;在adapters.py里調用自己的.py&#xff0c;通過所有的test。 作業資料參考 karpathy視頻倉庫&#xff1a; 視頻 github倉庫 測試項目運行環境 下載uv uv官網倉庫 使用命令&#xff1a; powershell -ExecutionPoli…

YOLOv11來了,使用YOLOv11訓練自己的數據集和推理(附YOLOv11網絡結構圖)

文章目錄前言一、YOLOv11代碼下載地址1.YOLOv11模型結構圖二、數據集準備1.數據集標注軟件2.voc數據集格式轉換3.數據集劃分4.修改yolo的訓練配置文件三、YOLO環境配置教程1.pytorch環境安裝2.其他依賴安裝四、YOLOv11訓練五、YOLOv11推理六、解決訓練過程中斷怎么繼續上次訓練…

20250731在榮品的PRO-RK3566開發板的Android13下跑通敦泰的FT8206觸控芯片

20250731在榮品的PRO-RK3566開發板的Android13下跑通敦泰的FT8206觸控芯片 2025/7/31 17:48緣起&#xff1a;本文前置條件&#xff1a;已經解決FT8206和PRO-RK3566的硬件連接。 通過i2cdect可以掃描到i2c從機地址&#xff1a;0x38。【8位地址為0x70】緣起&#xff1a;本文只分析…

異常檢測:算法分類及經典模型概覽

第一部分&#xff1a;異常檢測的核心概念 在深入算法細節之前&#xff0c;理解異常檢測的“語境”至關重要。 1. 什么是異常檢測&#xff1f; 異常檢測&#xff08;Anomaly Detection 或 Outlier Detection&#xff09;旨在通過數據挖掘技術&#xff0c;識別出數據集中與大多數…

技術干貨 | 矢網DTF測量技術:透視線纜、天線與波導內部缺陷的“射頻X光”(二)

無線通信、雷達等領域中&#xff0c;射頻組件與傳輸系統的性能至關重要&#xff0c;其內部微小損傷易導致信號問題甚至系統失效。傳統測試無法精確定位故障點&#xff0c;排查困難。DTF測量&#xff0c;矢網賦予的“透視眼”&#xff01;它能穿透“黑箱”&#xff0c;精確定位線…

【[CSP-J 2022] 上升點列】

題目 [CSP-J 2022] 上升點列 題目描述 在一個二維平面內&#xff0c;給定 n 個整數點 (x i ,y i? )&#xff0c;此外你還可以自由添加 k 個整數點。 你在自由添加 k 個點后&#xff0c;還需要從 nk 個點中選出若干個整數點并組成一個序列&#xff0c;使得序列中任意相鄰兩點間…

Kong API Gateway的十年進化史

一、技術基因的誕生&#xff08;2007-2015&#xff09; 2007年&#xff0c;三位意大利開發者Augusto Marietti、Marco Palladino和Michele Orru在博洛尼亞的一個小車庫中創立了Mashape公司。 最初他們開發了一個名為Mashup的API聚合平臺&#xff0c;試圖通過整合第三方API為開發…

藍牙設備配對:從機發現主機全過程

在藍牙 paging 過程中&#xff0c;從設備&#xff08;Slave&#xff09;是通過特定的掃描機制和跳頻方式來發現主設備發送的 ID 包的&#xff0c;具體過程如下&#xff1a;從設備處于特定掃描模式&#xff1a;從設備需要處于 Page Scan 模式&#xff0c;才能夠接收主設備發送的…

聚觀早報 | 三星獲特斯拉AI芯片訂單;小米16首發成安卓最強SOC;iPhone 17 Pro支持8倍光學變焦

聚觀早報每日整理最值得關注的行業重點事件&#xff0c;幫助大家及時了解最新行業動態&#xff0c;每日讀報&#xff0c;就讀聚觀365資訊簡報。整理丨肖羽7月29日消息三星獲特斯拉AI芯片訂單小米16首發成安卓最強SOCiPhone 17 Pro支持8倍光學變焦寧德時代滑板底盤公司啟動首輪融…

Gemini Fullstack LangGraph Quickstart(DeepSeek+Tavily版本)

文章目錄參考資料說明Gemini Fullstack LangGraph QuickstartDeepSeek Fullstack LangGraph Quickstart項目部署完整源碼地址后端部署前端部署參考資料 DeepResearch應用開發實戰網盤課件資料 說明 本文僅供學習和交流使用&#xff0c;感謝賦范社區相關老師的辛苦付出&#…

鋼筋計數誤差↓78%!陌訊多模態融合算法在建筑地產AI質檢的落地實踐

?摘要??針對建筑地產行業鋼筋驗收場景的高誤差痛點&#xff0c;本文解析陌訊視覺算法的多模態融合架構如何實現毫米級精度目標檢測。實測顯示&#xff1a;在Jetson Xavier NX邊緣設備上&#xff0c;鋼筋計數mAP0.5達??92.4%??&#xff0c;較基線模型提升28個百分點&…

負載均衡 LoadBalance

問題引入 我們一個服務可能會進行多機部署&#xff0c;也就說多臺服務器組成的集群共同對外提供一致的服務&#xff0c;那么我們的微服務的代碼就需要拷貝多份&#xff0c;部署到不同的機器上。 我們使用 IDEA 來開啟多個相同的服務 這里以 product-service 為例&#xff1a;…

13. 若依框架中的 Sensitive 敏感字段過濾

若依框架中有Sensitive注解&#xff0c;但代碼中并未使用&#xff0c;但該注解的實現還是比較值的學習的。該注解是一個運行時注解該注解只能應用在字段上JacksonAnnotationsInside 表示當使用Jackson序列化時&#xff0c;Jackson會自動識別該注解下的其他Jackson相關注解&…

git本地倉庫,工作區和暫存區的知識

一 git工作原理 Git 的工作原理基于分布式版本控制&#xff0c;通過管理文件的不同版本狀態&#xff0c;實現代碼的追蹤、協作和回溯。除了常見的工作區&#xff08;Working Directory&#xff09; 和暫存區&#xff08;Staging Area/Index&#xff09;&#xff0c;核心還包括本…

MPU6050模塊

一&#xff1a;MPU6050簡介輸出一個隨姿態變化而變化的電壓&#xff0c;想要量化電壓&#xff0c;就得使用ADC轉化歐拉角偏航角&#xff08;Yaw&#xff09;&#xff1a;也叫航向角&#xff0c;通常是繞 z 軸旋轉的角度&#xff0c;以 x 軸正向為起始邊&#xff0c;旋轉后 x 軸…

jvm的棧和堆

在 JVM 中&#xff0c;棧&#xff08;Stack&#xff09;和堆&#xff08;Heap&#xff09;是兩種核心內存區域&#xff0c;用于存儲不同類型的數據&#xff0c;它們的設計和存儲規則有明確區分&#xff0c;主要體現在存儲內容、生命周期和管理方式上&#xff1a;一、棧&#xf…