swift-12-Error處理、關聯類型、assert、泛型_

一、錯誤類型

開發過程常見的錯誤
語法錯誤(編譯報錯)
邏輯錯誤
運行時錯誤(可能會導致閃退,一般也叫做異常)

2.1 通過結構體

第一步
struct MyError : Errort {
var msg: String
}
第二步
func divide(_ num1: Int, - num2: Int) throws -> Int ?
if num2 == 0 {
第三步
throw MyError(msg:"0不能作為除數")
}
return numi / num2
}
divide (1,0)

2.2 枚舉定義錯誤信息

Swift中可以通過Error協議自定義運行時的錯誤信息

enum SomeError : Error {
case illegalArg(String)
case outOfBounds(Int, Int) case outOfMemory
}

?函數內部通過throw拋出自定義Error?,可能會拋出Error的函數必須加上throws聲明

func divide(_ num1: Int, _ num2: Int) throws -> Int {
if num2 == 0 {
throw SomeError.illegalArg("0不能作為除數")
}
return num1 / num2
}

需要使用try調用可能會拋出Error的函數

var result = try divide(20, 10)

2.3 處理錯誤信息do-catch

可以使用do-catch捕捉Error

func test {
print ("1")
do {
print ("2")
print(try divide (200, 0))
//一旦這句回拋出異常,do作用越后邊的代碼都不會執行,也就是后邊的都不會執行
print ("3")
print ("3")
print ("3")
print ("3" )
print ("3")
? catch let SomeError.illegalArg(msg) ?
print ("參數異常:",msg)
} catch let SomeError.outOfBounds(size, index) {
print("下標越界:","size=\(size)",
, "index=\(index)")
} catch SomeError.outOfMemory 1
print("內存溢出")
? catch {
print("其他錯誤")
print ("4")
}test()
// 1
// 2
// 參數異常 : 0不能作為除數 // 4這種方式和上面的那種方式一樣,先拿到所有的error 再casedo {
try divide(20, 0)
} catch let error {
switch error {
case let SomeError.illegalArg(msg):
print("參數錯誤: ", msg)default:
print("其他錯誤")
}
}

拋出Error后,try下一句直到作用域結束的代碼都將停止運行

2.4?處理Error

處理Error的2種方式
① ?通過do-catch捕捉Error
② ?不捕捉Error ,在當前函數增加throws聲明,Error將自動拋給上層函數
?如果最頂層函數( main函數)依然沒有捕捉Error ,那么程序將終止

這里拋給調用者處理
func test() throws {
print("1")
print(try divide(20, 0))
print("2")
}
try test()
// 1
// Fatal error: Error raised at top level處理方式一
do {
print(try divide(20, 0))
} catch is SomeError {
print("SomeError")
}處理方式二
func test() throws {
print("1")
do {
print("2")
print(try divide(20, 0))
print("3")
} catch let error as SomeError {
print(error)
}
print("4")
}
try test()
// 1
// 2
// illegalArg("0不能作為除數") // 4

2.5 注意點

func testo(){
test1 ()
}func test1() {
test2 ()
}
func test2() {
do {
print(try divide (200, 0)) 2 
如果這里只寫一個catch的情況還是回報錯,告訴你沒有處理所有的錯誤信息
} catch is SomeError {
print ("This is SomeError")
}解決辦法
func test2) {
do {
print(try divide (200, 0))
} catch is SomeError {
print ("This is SomeError")
} catch {
}
}或者往上拋
func test0()throws {
try test1()
}
}
func test1() throws {
try test2()
}func test2() throws {
do {
print(try divide (200,0))
}catch is SomeError {
print ("This is SomeError")}
}

二、try?、?try!

?可以使用try?、 try!調用可能會拋出Error的函數,這樣就不用去處理Error

func test() {
print("1")
var result1 = try? divide(20, 10) // Optional(2), Int?
var result2 = try? divide(20, 0) // nil
var result3 = try! divide(20, 10) // 2, Int
print("2")
}
test()a、 b是等價的
var a = try? divide(20, 0) var b: Int?
do {
b = try divide(20, 0)
} catch { b = nil }

三、rethrows

rethrows表明:函數本身不會拋出錯誤,但調用閉包參數拋出錯誤,那么它會將錯誤向上拋

func exec(_ fn: (Int, Int) throws -> Int, _ num1: Int, _ num2: Int) rethrows {
print(try fn(num1, num2))
}
// Fatal error: Error raised at top level
try exec(divide, 20, 0)

四、defer

defer語句:用來定義以任何方式(拋錯誤、?return等)離開代碼塊前必須要執行的代碼

defer語句將延遲至當前作用域結束之前執行

func open(_ filename: String) -> Int {
print("open")
return 0
}
func close(_ file: Int) {
print("close")
}func processFile(_ filename: String) throws {
let file = open(filename)
defer {
close(file)
}
// 使用file // ....
try divide(20, 0)// close將會在這里調用
}
try processFile("test.txt")
// open
// close
// Fatal error: Error raised at top level

defer語句的執行順序與定義順序相反

func fn1() { print("fn1") }
func fn2() { print("fn2") }
func test() {
defer { fn1() }
defer { fn2() }
}
test()
// fn2
// fn1

二、泛型(Generics?

2.1 范型函數的定義和普通函數的定義的區別

swapValues<T> 這里要加<T> 表示范型函數

型可以將類型參數化,提高代碼復用率,減少代碼量

func swapValues<T>(_ a: inout T, _ b: inout T) {
(a, b) = (b, a)
}var i1 = 10 var i2 = 20
swapValues(&i1, &i2)var d1 = 10.0 var d2 = 20.0
swapValues(&d1, &d2)struct Date {
var year = 0, month = 0, day = 0
}
var dd1 = Date(year: 2011, month: 9, day: 10)
var dd2 = Date(year: 2012, month: 10, day: 11)
swapValues(&dd1, &dd2)

泛型函數賦值給變量

func test<T1, T2>(_ t1: T1, _ t2: T2) {}
var fn: (Int, Double) -> () = test

2.2?泛型類型

2.2.1 泛型類型類

class Stack<E> {
var elements = [E]()
func push(_ element: E) { elements.append(element) }
func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}var stack = Stack<Int>()
stack.push(11)
stack.push(22)
stack.push(33)
print(stack.top()) // 33
print(stack.pop()) // 33
print(stack.pop()) // 22
print(stack.pop()) // 11
print(stack.size()) // 0

2.2.2?泛型類型 繼承

class SubStack<E> : Stack<E> {}

2.2.3?泛型類型結構體

struct Stack<E> {
var elements = [E]()
mutating func push(_ element: E) { elements.append(element) }
mutating func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}

2.2.4?泛型類型枚舉

enum Score<T> {
case point(T)
case grade(String)
}
let score0 = Score<Int>.point(100)
let score1 = Score.point(99)
let score2 = Score.point(99.5)
let score3 = Score<Int>.grade("A")

三、關聯類型(Associated?Type) 協議范型的表示方法

關聯類型的作用:給協議中用到的類型定義一個占位名稱

協議中可以擁有多個關聯類型

protocol Stackable {
associatedtype Element // 關聯類型
mutating func push(_ element: Element)
mutating func pop() -> Element
func top() -> Element
func size() -> Int
}class StringStack : Stackable {
// 給關聯類型設定真實類型
// typealias Element = String
var elements = [String]()
func push(_ element: String) { elements.append(element) }
func pop() -> String { elements.removeLast() }
func top() -> String { elements.last! }
func size() -> Int { elements.count }
}
var ss = StringStack()
ss.push("Jack")
ss.push("Rose")class Stack<E> : Stackable {
// typealias Element = E
var elements = [E]()
func push(_ element: E) {
elements.append(element)
}
func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}

四、類型約束 1.50?

T : Person & Runnable 約束T 遵守Runnable并且是Person類型protocol Runnable { }
class Person { }
func swapValues<T : Person & Runnable>(_ a: inout T, _ b: inout T) {
(a, b) = (b, a)
}
protocol Stackable {
associatedtype Element : Equatable
}
class Stack<E : Equatable> : Stackable 1
typealias I
Element = E
}
protocol Stackable {
associatedtype Element: Equatable
}
class Stack<E : Equatable> : Stackable { typealias Element = E }
func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _ s2: S2) -> Bool
where S1.Element == S2.Element, S1.Element : Hashable {
return false
}var stack1 = Stack<Int>()
var stack2 = Stack<String>()
// error: requires the types 'Int' and 'String' be equivalent
equal(stack1, stack2)

四、協議類型的注意點 2.00

protocol Runnable {}
class Person : Runnable {}
class Car : Runnable {}func get(_ type: Int) -> Runnable {
if type == 0 {
return Person()
}
return Car()
}var r1 = get(0)
var r2 = get(1)如果協議中有associatedtypeprotocol Runnable {
associatedtype Speed
var speed: Speed { get }
}
class Person : Runnable {
var speed: Double { 0.0 }
}
class Car : Runnable {
var speed: Int { 0 }
}

4.1?泛型解決

?解決方案①?:使用泛型

func get<T : Runnable>(_ type: Int) -> T {
if type == 0 {
return Person() as ! T
}
return Car() as ! T
}
var r1: Person = get(0)
var r2: Car = get(1)

4.2、不透明類型(Opaque?Type

func get(_ type: Int) -> some Runnable { Car() }
var r1 = get(0)
var r2 = get(1)
some限制只能返回一種類型

五、some

some 解決Runnable帶有關聯類型的報錯的問題

some除了用在返回值類型上,一般還可以用在屬性類型上

protocol Runnable { associatedtype Speed }
class Dog : Runnable { typealias Speed = Double }
class Person {
var pet: some Runnable {
return Dog()
}
}

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

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

相關文章

實驗擴充 LED顯示4*4鍵位值

代碼功能概述 鍵盤掃描&#xff1a; 使用 KeyPort&#xff08;定義為 P1&#xff09;作為鍵盤輸入端口。掃描 4x4 矩陣鍵盤&#xff0c;檢測按鍵并返回按鍵編號&#xff08;0~15&#xff09;。 數碼管顯示&#xff1a; 根據按鍵編號&#xff0c;從 SegCode 數組中獲取對應數碼…

從零開始搭建CLIP模型實現基于文本的圖像檢索

目錄 CLIP原理簡介代碼實現參考鏈接 CLIP原理簡介 論文鏈接&#xff0c;源碼鏈接 CLIP模型由OpenAI在2021年提出&#xff0c;利用雙Decoder&#xff08;Dual Encoder&#xff09;的架構來學習圖像和文本之間的對應關系&#xff0c;是多模態大模型的開創之作&#xff0c;為后續許…

熊海cms代碼審計

目錄 sql注入 1. admin/files/login.php 2. admin/files/columnlist.php 3. admin/files/editcolumn.php 4. admin/files/editlink.php 5. admin/files/editsoft.php 6. admin/files/editwz.php 7. admin/files/linklist.php 8. files/software.php 9. files…

[Java微服務組件]注冊中心P3-Nacos中的設計模式1-觀察者模式

在P1-簡單注冊中心實現和P2-Nacos解析中&#xff0c;我們分別實現了簡單的注冊中心并總結了Nacos的一些設計。 本篇繼續看Nacos源碼&#xff0c;了解一下Nacos中的設計模式。 目錄 Nacos 觀察者模式 Observer Pattern觀察者模式總結 Nacos 觀察者模式 Observer Pattern 模式定…

電腦 訪問 github提示 找不到網頁,處理方案

1、找到 本機的 host文件 例如 windows 的 一般在 C:\Windows\System32\drivers\etc\hosts 用管理員身份打開 hosts 文件 如果文件中沒有 github的配置&#xff0c;需要自己手動添加上去&#xff1b; 如果有&#xff0c;則需要 檢查 github.com 與 github.global.ssl.fastly.…

Linux系統中的網絡管理

1.RHEL9版本中&#xff0c;使用nm進行網絡配置&#xff0c;ifcfg不再是網絡配置文件的主存儲&#xff0c;樣式仍然可用&#xff0c;但它不再是NetworkManger存儲新網絡配置文件的默認位置&#xff0c;RHEL以key-file格式在etc/NetworkManger/system-connections/中存儲新的網絡…

AI技術深度解析:從移動芯片到AIoT的全面突破

作為全球無線通信技術和半導體解決方案的重要參與者,高通始終將技術創新作為核心驅動力,在移動通信、物聯網(IoT)、汽車電子、AI計算等領域占據關鍵地位。本文將從其核心產品線、技術突破、應用場景及未來布局四個維度,客觀解析高通的技術積累與行業角色。 一、核心產品線…

使用CS Roofline Toolkit測量帶寬

使用CS Roofline Toolkit測量帶寬 工程下載&#xff1a;使用CS Roofline Toolkit測量帶寬-案例工程文件&#xff0c;也可以按照下面的說明使用git clone下載 目錄 使用CS Roofline Toolkit測量帶寬0、Roofline模型理解1、CS Roofline Toolkit下載1.1、設置代理1.2、git clone下…

EAGLE代碼研讀+模型復現

要對代碼下手了&#xff0c;加油(? ?_?)? 作者在他們自己的設備上展現了推理的評估結果&#xff0c;受第三方評估認證&#xff0c;EAGLE為目前最快的投機方法&#xff08;雖然加速度是評估投機解碼方法的主要指標&#xff0c;但其他點也值得關注。比如PLD和Lookahead無需額…

基于SFC的windows修復程序,修復絕大部分系統損壞

效果:可以自動修復大部分由系統文件損壞而導致的錯誤 例如:系統應用無法打開 系統窗口(例如開始菜單)無法使用 電腦藍屏或者卡死.....文章 01技術背景 Windows自帶了一個SFC命令行應用程序,可以檢查大部分的系統文件錯誤,以及復這些文件 其中自動檢查所有系統文件&#x…

liunx日志問題

一、日志定向 Linux 系統的日志配置文件&#xff08;如/etc/syslog.conf或/etc/rsyslog.conf &#xff09;中&#xff0c;用于定義系統日志的記錄規則&#xff0c;決定哪些類型的日志消息會被記錄到特定的日志文件中。 *.info;mail.none;authpriv.none;cron.none /va…

2.凸包優化求解

1.減而治之(Decrease and Conquer) 插入排序 典型的減而治之算法就是插入排序方法 插入排序法: 在未排序中選擇一個元素&#xff0c;插入到已經排序號的序列中 將凸包也采用減而治之的方法 2.In-Convex-Polygon Test 怎么判斷引入的極點存在于多邊形里面還是外面&#xff1…

系統思考:危機中的轉型機遇

“危機不僅是挑戰&#xff0c;更是轉型的機會” 每當大事發生&#xff0c;很多企業老板常常被眼前的困境壓得喘不過氣&#xff0c;焦慮與壓力讓人難以思考長遠。特別是在危機面前&#xff0c;大家忙于應對眼前的風險&#xff0c;卻忽略了背后隱藏的機遇。而危機&#xff0c;恰…

大模型Rag - 如何評估Rag

一.RAG流程與評估標準補充 RAG&#xff08;Retrieval-Augmented Generation&#xff09;是一種結合檢索與生成的問答架構。為了確保系統效果&#xff0c;需要從以下三個角度對其評估&#xff1a; 回顧RAG流程 用戶提出問題 → 系統檢索相關上下文 → 基于上下文由大語言模型…

Linux RT RT RT

RT的最終目的是盡可能多的讓原來系統不可搶占的部分變成可搶占&#xff0c;讓高優先級的程序先跑。這里的rt引入了一個deadline的說法&#xff0c;此時的實時性是保證在最大一個時間間隔內&#xff0c;程序被執行。比如每100ms算法做一次決策。 所以此時面臨著幾座大山…

演員柳琦正式加入創星演員出道計劃,開創演藝事業新天地

4月18日&#xff0c;演員柳琦正式加入“創星演員出道計劃”&#xff0c;不僅得到參演都市愛情喜劇《和我結婚吧》角色的機會&#xff0c;還獲得文旅精品網劇《醉夢靈州》的出演機會&#xff0c;自此開啟全新影視之路。對表演藝術極具天賦的柳琦&#xff0c;相信未來可以憑借自身…

16.Chromium指紋瀏覽器開發教程之WebGPU指紋定制

WebGPU指紋概述 WebGPU是下一代的Web圖形和計算API&#xff0c;旨在提供高性能的圖形渲染和計算能力。它是WebGL的后繼者&#xff0c;旨在利用現代GPU的強大功能&#xff0c;使得Web應用能夠實現接近原生應用的圖形和計算性能。而且它是一個低級別的API&#xff0c;可以直接與…

HTTP:九.WEB機器人

概念 Web機器人是能夠在無需人類干預的情況下自動進行一系列Web事務處理的軟件程序。人們根據這些機器人探查web站點的方式,形象的給它們取了一個飽含特色的名字,比如“爬蟲”、“蜘蛛”、“蠕蟲”以及“機器人”等!爬蟲概述 網絡爬蟲(英語:web crawler),也叫網絡蜘蛛(…

Vue3+TS中svg圖標的使用

安裝依賴 pnpm i vite-plugin-svg-icons -D配置引入 vite.config.ts ... import { createSvgIconsPlugin } from vite-plugin-svg-icons import path from node:pathconst svgIconsPlugin createSvgIconsPlugin({iconDirs: [path.resolve(process.cwd(), src/assets/icons)]…

【java實現+4種變體完整例子】排序算法中【堆排序】的詳細解析,包含基礎實現、常見變體的完整代碼示例,以及各變體的對比表格

以下是堆排序的詳細解析&#xff0c;包含基礎實現、常見變體的完整代碼示例&#xff0c;以及各變體的對比表格&#xff1a; 一、堆排序基礎實現 原理 基于二叉堆結構&#xff08;最大堆&#xff09;&#xff0c;通過以下步驟實現排序&#xff1a; 構建最大堆&#xff1a;將…