ts學習2

JavaScript 中的每個值都有一組行為,您可以通過運行不同的操作來觀察這些行為。這聽起來很抽象,但作為一個簡單的例子,考慮我們可能在名為?message?的變量上運行的一些操作。

// Accessing the property 'toLowerCase'
// on 'message' and then calling it
message.toLowerCase();// Calling 'message'
message();

如果我們將其分解,第一行可運行的代碼會訪問一個名為?toLowerCase?的屬性,然后調用它。第二個嘗試直接調用?message

但是假設我們不知道?message?的值——這很常見——我們不能可靠地說明嘗試運行這些代碼會得到什么結果。每個操作的行為完全取決于我們最初擁有的價值。

  • message?可以調用嗎?
  • 它上面是否有一個名為?toLowerCase?的屬性?
  • 如果是這樣,toLowerCase?甚至可以調用嗎?
  • 如果這兩個值都是可調用的,它們會返回什么?

這些問題的答案通常是我們在編寫 JavaScript 時牢記在心的事情,我們必須希望我們得到了正確的所有細節。

假設?message?是按以下方式定義的。

const message = "Hello World!";

正如您可能猜到的,如果我們嘗試運行?message.toLowerCase(),我們將只得到相同的小寫字符串。

那第二行代碼呢?如果您熟悉 JavaScript,您會知道這會失敗并出現異常:

TypeError: message is not a function

如果我們能避免這樣的錯誤,那就太好了。

當我們運行我們的代碼時,我們的 JavaScript 運行時選擇做什么的方式是確定值的類型——它具有什么樣的行為和能力。這就是?TypeError?所暗示的部分內容——它表示字符串?"Hello World!"?不能作為函數調用。

對于某些值,例如原語?string?和?number,我們可以在運行時使用?typeof?運算符識別它們的類型。但是對于其他的東西,比如函數,沒有相應的運行時機制來識別它們的類型。例如,考慮這個函數:

function fn(x) {return x.flip();
}

我們可以通過閱讀代碼觀察到,這個函數只有在給定一個具有可調用?flip?屬性的對象時才能工作,但 JavaScript 不會以我們可以在代碼運行時檢查的方式顯示這些信息。在純 JavaScript 中,判斷?fn?對特定值做了什么的唯一方法是調用它并查看會發生什么。這種行為使得在運行之前很難預測代碼會做什么,這意味著在編寫代碼時更難知道代碼會做什么。

這樣看,類型就是描述哪些值可以傳遞給fn,哪些會崩潰的概念。JavaScript 僅真正提供動態類型 - 運行代碼以查看發生了什么。

另一種方法是使用靜態類型系統在運行之前預測預期的代碼。

?靜態類型檢查

回想一下我們之前嘗試將?string?作為函數調用而得到的?TypeError。大多數人不喜歡在運行他們的代碼時遇到任何類型的錯誤——那些被認為是錯誤!當我們編寫新代碼時,我們會盡力避免引入新的錯誤。

如果我們只添加一點代碼,保存我們的文件,重新運行代碼,然后立即看到錯誤,我們也許可以快速隔離問題;但情況并非總是如此。我們可能沒有對這個功能進行足夠徹底的測試,所以我們可能永遠不會真正遇到可能拋出的潛在錯誤!或者,如果我們有幸目睹了這個錯誤,我們可能最終會進行大規模的重構并添加許多我們不得不挖掘的不同代碼。

理想情況下,我們可以有一個工具來幫助我們在代碼運行之前找到這些錯誤。這就是像 TypeScript 這樣的靜態類型檢查器所做的。靜態類型系統描述了當我們運行程序時我們的值的形狀和行為。像 TypeScript 這樣的類型檢查器使用這些信息并告訴我們什么時候事情可能會出軌。

const message = "hello!";message();

在我們首先運行代碼之前,使用 TypeScript 運行最后一個示例會給我們一個錯誤消息。

?非異常故障

到目前為止,我們一直在討論某些事情,比如運行時錯誤——JavaScript 運行時告訴我們它認為某些事情是荒謬的情況。出現這些情況是因為?ECMAScript 規范?明確說明了語言在遇到意外情況時應該如何表現。

例如,規范說嘗試調用不可調用的東西應該會引發錯誤。也許這聽起來像 "obvious behavior",但您可以想象訪問對象上不存在的屬性也會引發錯誤。相反,JavaScript 為我們提供了不同的行為并返回值?undefined

const user = {name: "Daniel",age: 26,
};user.location; // returns undefined

最終,靜態類型系統必須調用其系統中應將哪些代碼標記為錯誤,即使是不會立即拋出錯誤的 "valid" JavaScript。在 TypeScript 中,以下代碼會產生關于?location?未定義的錯誤:

const user = {name: "Daniel",age: 26,
};user.location;

雖然有時這意味著在您可以表達的內容上進行權衡,但其目的是捕捉我們程序中的合法錯誤。TypeScript 捕獲了很多合法的錯誤。

例如:錯別字,

const announcement = "Hello World!";// How quickly can you spot the typos?
announcement.toLocaleLowercase();
announcement.toLocalLowerCase();// We probably meant to write this...
announcement.toLocaleLowerCase();

未調用的函數,

function flipCoin() {// Meant to be Math.random()return Math.random < 0.5;
}

或基本邏輯錯誤。

const value = Math.random() < 0.5 ? "a" : "b";
if (value !== "a") {// ...
} else if (value === "b") {// Oops, unreachable
}

?工具類型

當我們在代碼中出錯時,TypeScript 可以捕獲錯誤。這很好,但 TypeScript 也可以從一開始就阻止我們犯這些錯誤。

類型檢查器具有檢查諸如我們是否正在訪問變量和其他屬性的正確屬性之類的信息。一旦有了這些信息,它還可以開始建議您可能想要使用哪些屬性。

這意味著 TypeScript 也可以用于編輯代碼,核心類型檢查器可以在您在編輯器中鍵入時提供錯誤消息和代碼完成。這是人們在談論 TypeScript 工具時經常提到的部分內容。

import express from "express";
const app = express();app.get("/", function (req, res) {res.sen
//       ^|
});app.listen(3000);

TypeScript 非常重視工具,這超出了您鍵入時的完成和錯誤。支持 TypeScript 的編輯器可以提供 "quick fixes" 以自動修復錯誤、重構以輕松重新組織代碼,以及用于跳轉到變量定義或查找對給定變量的所有引用的有用導航功能。所有這些都建立在類型檢查器之上,并且是完全跨平臺的,所以很可能是?你最喜歡的編輯器支持 TypeScript。

?tsc,TypeScript 編譯器

我們一直在談論類型檢查,但我們還沒有使用我們的類型檢查器。讓我們熟悉一下我們的新朋友?tsc,TypeScript 編譯器。首先,我們需要通過 npm 獲取它。

npm install -g typescript

這將全局安裝 TypeScript 編譯器?tsc。如果您希望從本地?node_modules?包運行?tsc,則可以使用?npx?或類似工具。

現在讓我們移動到一個空文件夾并嘗試編寫我們的第一個 TypeScript 程序:hello.ts

// Greets the world.
console.log("Hello world!");

請注意,這里沒有多余的裝飾;這個 "hello world" 程序看起來和你用 JavaScript 編寫的 "hello world" 程序一樣。現在讓我們通過運行?typescript?包為我們安裝的命令?tsc?來檢查它。

tsc hello.ts

Tada!

等等,到底 "tada" 什么?我們跑了?tsc,什么也沒發生!好吧,沒有類型錯誤,所以我們沒有在控制臺中得到任何輸出,因為沒有什么要報告的。

但再次檢查 - 我們得到了一些文件輸出。如果我們查看當前目錄,我們會在?hello.ts?旁邊看到一個?hello.js?文件。這是?tsc?編譯或轉換為純 JavaScript 文件后我們的?hello.ts?文件的輸出。如果我們檢查內容,我們會看到 TypeScript 在處理?.ts?文件后會吐出什么:

// Greets the world.
console.log("Hello world!");

在這種情況下,TypeScript 幾乎不需要轉換,所以它看起來和我們寫的一樣。編譯器試圖發出看起來像人會寫的東西的干凈可讀的代碼。雖然這并不總是那么容易,但 TypeScript 會始終如一地縮進,注意我們的代碼何時跨越不同的代碼行,并試圖保留注釋。

如果我們確實引入了類型檢查錯誤怎么辦?讓我們重寫hello.ts

// This is an industrial-grade general-purpose greeter function:
function greet(person, date) {console.log(`Hello ${person}, today is ${date}!`);
}greet("Brendan");

如果我們再次運行?tsc hello.ts,請注意我們在命令行上收到錯誤!

Expected 2 arguments, but got 1.

TypeScript 告訴我們,我們忘記將參數傳遞給?greet?函數,這是理所當然的。到目前為止,我們只編寫了標準的 JavaScript,但類型檢查仍然能夠發現我們代碼的問題。感謝 TypeScript!

?使用錯誤觸發

從上一個示例中您可能沒有注意到的一件事是我們的?hello.js?文件再次更改。如果我們打開該文件,我們會看到內容與我們的輸入文件看起來基本相同。考慮到?tsc?報告了關于我們的代碼的錯誤,這可能有點令人驚訝,但這是基于 TypeScript 的核心價值之一:很多時候,你會比 TypeScript 更了解。

重申一下,類型檢查代碼限制了您可以運行的程序種類,因此需要權衡類型檢查器認為可以接受的類型。大多數時候沒關系,但在某些情況下,這些檢查會妨礙您。例如,假設您將 JavaScript 代碼遷移到 TypeScript 并引入類型檢查錯誤。最終,您將開始為類型檢查器清理東西,但原始的 JavaScript 代碼已經可以工作了!為什么要將其轉換為 TypeScript 會阻止您運行它?

所以 TypeScript 不會妨礙你。當然,隨著時間的推移,您可能希望對錯誤更加防御,并使 TypeScript 的行為更加嚴格。在這種情況下,您可以使用?noEmitOnError?編譯器選項。嘗試更改您的?hello.ts?文件并使用該標志運行?tsc

tsc --noEmitOnError hello.ts

您會注意到?hello.js?永遠不會更新。

?顯式的類型

到目前為止,我們還沒有告訴 TypeScript?person?或?date?是什么。讓我們編輯代碼來告訴 TypeScript?person?是一個?string,而?date?應該是一個?Date?對象。我們還將在?date?上使用?toDateString()?方法。

function greet(person: string, date: Date) {console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}

我們所做的是在?person?和?date?上添加類型注釋來描述可以使用哪些類型的值來調用?greet。您可以將該簽名讀作 "greet?takes a?person?of type?string, and a?date?of type?Date"。

有了這個,TypeScript 可以告訴我們?greet?可能被錯誤調用的其他情況。例如...

function greet(person: string, date: Date) {console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}greet("Maddison", Date());

嗯? TypeScript 在我們的第二個參數上報告了一個錯誤,但是為什么呢?

也許令人驚訝的是,在 JavaScript 中調用?Date()?返回一個?string。另一方面,用?new Date()?構造一個?Date?實際上給了我們所期望的結果。

無論如何,我們可以快速修復錯誤:

function greet(person: string, date: Date) {console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}greet("Maddison", new Date());

請記住,我們并不總是必須編寫顯式類型注釋。在許多情況下,TypeScript 甚至可以為我們推斷(或 "figure out")類型,即使我們省略它們。

let msg = "hello there!";

即使我們沒有告訴 TypeScript?msg?有?string?類型,它也能夠弄清楚這一點。這是一個特性,當類型系統最終會推斷出相同的類型時,最好不要添加注釋。

注意:如果您將鼠標懸停在該單詞上,則上一個代碼示例中的消息氣泡是您的編輯器將顯示的內容。

?擦除的類型

讓我們看看當我們用?tsc?編譯上面的函數?greet?以輸出 JavaScript 時會發生什么:

function greet(person: string, date: Date) {console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}greet("Maddison", new Date());

這里注意兩點:

  1. 我們的?person?和?date?參數不再有類型注釋。
  2. 我們的 "template string" - 那個使用反引號(`?字符)的字符串 - 被轉換為帶有連接的純字符串。

稍后會詳細介紹第二點,但現在讓我們關注第一點。類型注釋不是 JavaScript 的一部分(或者 ECMAScript 是迂腐的),所以實際上沒有任何瀏覽器或其他運行時可以在未經修改的情況下運行 TypeScript。這就是 TypeScript 首先需要一個編譯器的原因——它需要某種方式來剝離或轉換任何 TypeScript 特定的代碼,以便您可以運行它。大多數特定于 TypeScript 的代碼都被刪除了,同樣地,我們的類型注釋也被完全刪除了。

記住:類型注釋永遠不會改變程序的運行時行為。

?降級

與上面的另一個區別是我們的模板字符串是從

`Hello ${person}, today is ${date.toDateString()}!`;

"Hello " + person + ", today is " + date.toDateString() + "!";

為什么會這樣?

模板字符串是 ECMAScript 版本中的一項功能,稱為 ECMAScript 2015(又名 ECMAScript 6、ES2015、ES6 等 - 不要問)。TypeScript 能夠將代碼從較新版本的 ECMAScript 重寫為較舊的版本,例如 ECMAScript 3 或 ECMAScript 5(又名 ES3 和 ES5)。從 ECMAScript 的新版本或 "higher" 版本向下移動到舊版本或 "lower" 版本的過程有時稱為降級。

默認情況下,TypeScript 以 ES3 為目標,這是一個非常舊的 ECMAScript 版本。通過使用?target?選項,我們可以選擇更新一點的東西。使用?--target es2015?運行將 TypeScript 更改為以 ECMAScript 2015 為目標,這意味著代碼應該能夠在任何支持 ECMAScript 2015 的地方運行。所以運行?tsc --target es2015 hello.ts?會給我們以下輸出:

function greet(person, date) {console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
greet("Maddison", new Date());

雖然默認目標是 ES3,但當前絕大多數瀏覽器都支持 ES2015。因此,大多數開發人員可以安全地將 ES2015 或更高版本指定為目標,除非與某些古老的瀏覽器的兼容性很重要。

?嚴格性

不同的用戶使用 TypeScript 在類型檢查器中尋找不同的東西。有些人正在尋找一種更寬松的選擇加入體驗,它可以幫助驗證他們程序的某些部分,并且仍然擁有不錯的工具。這是 TypeScript 的默認體驗,其中類型是可選的,推理采用最寬松的類型,并且不檢查潛在的?null/undefined?值。就像?tsc?在面對錯誤時觸發的一樣,這些默認設置是為了不妨礙你。如果您要遷移現有的 JavaScript,那么這可能是理想的第一步。

相比之下,許多用戶更喜歡讓 TypeScript 盡可能多地立即驗證,這就是該語言也提供嚴格設置的原因。這些嚴格性設置將靜態類型檢查從開關(無論是否檢查您的代碼)變成更接近調節器的東西。你把這個調節器調得越高,TypeScript 就會越多地為你檢查。這可能需要一些額外的工作,但一般來說,從長遠來看,它會為自己付出代價,并且可以進行更徹底的檢查和更準確的工具。如果可能,新的代碼庫應始終打開這些嚴格性檢查。

TypeScript 有幾個可以打開或關閉的類型檢查嚴格標志,除非另有說明,否則我們所有的示例都將在啟用所有這些標志的情況下編寫。CLI 中的?strict?標志或?tsconfig.json?中的?"strict": true?會同時將它們全部打開,但我們可以單獨選擇退出它們。您應該知道的兩個最大的是?noImplicitAny?和?strictNullChecks。

?noImplicitAny

回想一下,在某些地方,TypeScript 不會嘗試為我們推斷類型,而是回退到最寬松的類型:any。這并不是可能發生的最糟糕的事情——畢竟,回退到?any?只是簡單的 JavaScript 體驗。

然而,使用?any?通常會破壞使用 TypeScript 的初衷。您的程序類型越多,您獲得的驗證和工具就越多,這意味著您在編寫代碼時遇到的錯誤就越少。打開?noImplicitAny?標志將對任何類型隱式推斷為?any?的變量觸發錯誤。

?strictNullChecks

默認情況下,像?null?和?undefined?這樣的值可以分配給任何其他類型。這可以使編寫一些代碼更容易,但忘記處理?null?和?undefined?是世界上無數錯誤的原因 - 有些人認為它是?十億美元的錯誤!strictNullChecks?標志使處理?null?和?undefined?更加明確,讓我們不必擔心是否忘記處理?null?和?undefined

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

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

相關文章

k8s環境使用Operator部署Seaweedfs集群(下)

作者&#xff1a;閆乾苓 文章目錄4.4.3 部署seaweedfs集群4.4.4 驗證集群運行狀態4.4.5 測試集群功能4.4.3 部署seaweedfs集群 集群Yaml示例 apiVersion: seaweed.seaweedfs.com/v1 kind: Seaweed metadata:name: seaweed1namespace: default spec:image: chrislusf/seaweedf…

【橘子分布式】gRPC(理論篇)

一、簡介 我們在前面學習了thrift rpc的知識&#xff0c;我們從其中接觸到了IDL&#xff0c;編解碼協議&#xff0c;服務的遠程調用(調用遠程服務就像在在本地調用一樣)等各種概念。 其實我個人對thrift的使用并不多&#xff0c;我更多的是使用今天我們要提到的一個RPC框架稱之…

OSPF高級特性之GR

一、概述OSPF GR(Graceful Restart),在路由器發生故障或管理員干預的情況下重啟了OSPF進程時,重新構建控制平面時,轉發平面不受影響,仍可以正常轉發數據。在我們OSPF網絡環境當中,假設路由器為框式路由器,通常框式路由器有多個主控板,當主主控板發生故障時會切換到備主控板上。…

iOS 構建配置與 AdHoc 打包說明

iOS 構建配置與 AdHoc 打包說明 1. 背景 在 iOS 項目中&#xff0c;通常需要支持 多個環境的構建和分發&#xff0c;比如&#xff1a; 開發環境 (Debug) → 本地調試內測環境 (AdHoc) → 提供 QA / 產品經理測試預發布環境 (AdHoc_Release) → 和正式版配置一致&#xff0c;但通…

【52】MFC入門到精通——MFC串口助手(二)---通信版(發送數據 、發送文件、數據轉換、清空發送區、打開/關閉文件),附源碼

文章目錄1 完整 功能展示2 添加控件變量及聲明2.1 添加控件及變量2.2 SerialPortDlg.h: 頭文件3 函數實現3.1 數據發送3.1.2 寫數據、字符串轉3.2 發送文件3.2.1 打開文件3.2.2 發送文件3.3 清空發送區4 完整MFC項目項下載1 完整 功能展示 串口通信助手 頁面展示&#xff0c;功…

筆試——Day12

文章目錄第一題題目思路代碼第二題題目&#xff1a;思路代碼第三題題目&#xff1a;思路代碼第一題 題目 刪除公共字符 思路 模擬&#xff1a; 遇到需要刪除的字符&#xff0c;則不添加到結果中 代碼 第二題 題目&#xff1a; 兩個鏈表的第一個公共結點 思路 模擬&#x…

SpringMVC @ResponseBody注解詳解

概要ResponseBody是 Spring MVC 中的一個重要注解&#xff0c;用于指示方法的返回值應該直接作為 HTTP 響應體返回&#xff0c;而不是解析為視圖名稱。基本功能ResponseBody主要用于將Java對象轉換為HTTP響應體&#xff08;通常是JSON或XML&#xff09;繞過視圖解析器直接返回數…

劍指offer——模擬:順時針打印矩陣

模擬vector.size返回的是矩陣的行數&#xff0c;vector[0].size返回的是矩陣的列數先排除傳入的矩陣是空矩陣先計算上下左右的邊界只要邊界不重合&#xff0c;就不停止輸出&#xff0c;完成一個部分的打印&#xff0c;就將當前的一個邊界回收不可以在for循環結束的時候一起判斷…

electron-vite實踐成品項目

羊駝的工具箱 項目地址 推薦使用該版本 并且使用yarn進行安裝 node版本:v22.16.0 技術棧&#xff1a;electron vue3 vite pinia vuetify3 sequelize sqlite Q:為什么vue3要用 vue2的寫法 A:其實是因為剛開始用vue3的寫法感覺超級惡心 對屬性的賦值和方法的管理可觀性…

自學中醫筆記(一)

我的中醫自學筆記 Q&A 自學原因&#xff1a;最開始我也不太信中醫&#xff0c;我室友也說中醫太玄學了。由于我從小一直都很瘦&#xff0c;吃飯每次都吃得少&#xff0c;上大學那會兒171cm最多也才101斤&#xff0c;而且一年胃病要犯好幾次&#xff0c;后來無意中收獲了一篇…

3.1 WPF畫折線圖、直方圖、餅狀圖

本文看了博客WPF編程&#xff0c;Live Charts使用說明&#xff08;2&#xff09;——使用_func<chartpoint, string> labelpoint-CSDN博客&#xff0c;這里作為筆記用。 1.前端代碼 前端XAML文件代碼如下&#xff1a; <Window x:Class"livechart1.MainWindow&…

如何通過ATS/HTTPS數據防篡改來加密視頻?

文章目錄前言一、什么是ATS/HTTPS數據防篡改&#xff1f;二、ATS/HTTPS數據防篡改的實現原理三、如何零代碼實現ATS/HTTPS數據防篡改來加密視頻總結前言 未經保護的視頻流極易在傳輸途中遭遇竊聽、攔截或惡意篡改&#xff0c;不僅損害內容價值&#xff0c;更可能引發嚴重的安全…

Python并發模型:多線程與多進程的優劣對比與實戰應用

文章目錄多線程基礎概念多進程基礎概念多線程的優劣勢多進程的優劣勢實戰應用&#xff1a;網絡爬蟲實戰應用&#xff1a;圖像處理Python作為一門功能強大的編程語言&#xff0c;提供了多種并發模型&#xff0c;使得我們能夠在同一時間執行多個任務&#xff0c;從而提高程序的執…

Spring Boot 整合 Nacos 實戰教程:服務注冊發現與配置中心詳解

Spring Boot 整合 Nacos 教程&#xff08;3000字&#xff09; 一、Nacos 簡介 Nacos 是阿里巴巴開源的一個動態服務發現、配置管理和服務管理平臺&#xff0c;致力于幫助開發者更輕松地構建云原生應用。它支持多種注冊中心協議&#xff08;如 Dubbo、Spring Cloud、Kubernete…

VMware 虛擬機裝 Linux Centos 7.9 保姆級教程(附資源包)

安裝 VMware 17.5.1 centos 7.9 ? 1、下載資源包&#xff08;虛擬機鏡像&#xff09; VMware-17.5.1 安裝包秘鑰.zipLinux Centos 7.9 鏡像 2、centos 7.9 下載地址 1、Centos 官網 2、阿里巴巴鏡像站 3、查看網絡命令 ifconfig 或 ip addr 4、登陸服務器 ssh stark192.168.3…

STM32超聲波模塊

一&#xff1a;超聲波模塊1&#xff1a;工作原理采用IO觸發測距&#xff0c;給至少10us的高電平信號。 模塊自動發送8個40KHz的方波&#xff0c;自動檢測是否有信號返回。 有信號返回&#xff0c;通過IO輸出一高電平&#xff0c;高電平持續時間就是超聲波從發射到返回的時間聲波…

RK3568項目(十一)--linux驅動開發之mipi屏幕調試

目錄 一、引言 二、MIPI DSI 屏幕 ------>2.1、MIPI聯盟 ------------>2.1.1、多媒體部分 ------------>2.1.2、硬件協議 ------------>2.1.3、D-PHY功能模式及速率 ------------>2.1.4、分辨率計算 ------>2.2、MIPI-DSI硬件連接 ------>2.3、傳…

C語言小游戲——飛機大戰

目錄 引言 開發環境與工具準備 1. 開發環境配置 2. 資源文件準備 游戲設計與架構 1. 游戲核心數據結構 2. 游戲全局變量 游戲核心功能實現 1. 游戲初始化 2. 游戲主循環 3. 游戲渲染 4. 游戲狀態更新 關鍵游戲機制實現 1. 敵機生成系統 2. 碰撞檢測系統 3. 敵機…

SQLite的可視化界面軟件的安裝

1、如下圖所示&#xff0c;DB Browser軟件&#xff0c;在壓縮包中。2、首先解壓到一個文件夾中。例如&#xff08;D:\\DB Browser&#xff09;文件夾。解壓后的內容如下圖。3、將解壓后的DB Browser文件夾&#xff0c;剪切到D:\Program Files\目錄中。如下兩圖。win10操作系統下…

基于 STM32H743VIT6 的邊緣 AI 實踐:貓咪叫聲分類 CNN 網絡部署實戰(已驗證)中一些bug總結

前言前面發了一篇文章基于 STM32H743VIT6 的邊緣 AI 實踐&#xff1a;貓咪叫聲分類 CNN 網絡部署實戰&#xff08;已驗證&#xff09;。這里面有一些我遇到過的bug&#xff0c;當時基本都花了很長的時間才解決。這里將這些bug總結一下方便后續查閱。1.使用cubemx插件解析AI模型…