學習筆記 - Swfit 6.1 - 語法概覽

獲取版本號

swift -version

Hello world

print("Hello, world!")

末尾不需要分號

常量(let),變量(var)

var myVariable = 42
myVariable = 50
let myConstant = 42

可以顯式聲明變量類型,若沒有則隱式推斷,類似下面的Double

let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70

賦值同一類型

let label = "The width is "
let width = 94
// 去掉String報錯
// Binary operator '+' cannot be applied to operands of type 'String' and 'Int'
let widthLabel = label + String(width)

字符串中通過\(變量名)的方法得到變量的字符串表示

let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."

多行文本的寫法

// """ """ 包含的內容
let quotation = """Even though there's whitespace to the left,the actual lines aren't indented.Except for this line.Double quotes (") can appear without being escaped.I still have \(apples + oranges) pieces of fruit."""

數組/字典通過 [] 遍歷

var fruits = ["strawberries", "limes", "tangerines"]
fruits[1] = "grapes"var occupations = ["Malcolm": "Captain","Kaylee": "Mechanic",]
occupations["Jayne"] = "Public Relations"

自動擴容

fruits.append("blueberries")
print(fruits)

空數組/字典

fruits = []
occupations = [:]// 指定類型
let emptyArray: [String] = []
let emptyDictionary: [String: Float] = [:]

控制流

循環: for-in,while,repeat-while
條件: if

let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {if score > 50 {teamScore += 3} else {teamScore += 1}
}
print(teamScore)
// Prints "11"

if + 賦值

let scoreDecoration = if teamScore > 10 {"🎉"
} else {""
}
print("Score:", teamScore, scoreDecoration)

屬于語法糖,少寫一個賦值

var n = 2
while n < 100 {n *= 2
}
print(n)
// Prints "128"var m = 2
// 這個其它語言中一般是用do, 用repeat可能是為了強調循環?
repeat {m *= 2
} while m < 100
print(m)
// Prints "128"
var total = 0
for i in 0..<4 {total += i
}
print(total)
// Prints "6"

for i in 0..<4, i的遍歷區間是0,1,2,3

可選型(optional)

  1. 類型后面跟問號
  2. if let name = optionalName 會解包,能確定namenil還是有具體的值
var optionalString: String? = "Hello"
print(optionalString == nil)
// Prints "false"var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {greeting = "Hello, \(name)"print(greeting)
}

還有種處理可選型的方法是通過??

let nickname: String? = nil
let fullName: String = "John Appleseed"
let informalGreeting = "Hi \(nickname ?? fullName)"

nickname 有值則用nickname的值,沒有值則用??后的值。這是種默認值的寫法,更健壯的處理當數據可能為nil的情況。

switch 的寫法

let vegetable = "red pepper"
switch vegetable {
case "celery":print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):print("Is it a spicy \(x)?")
default:print("Everything tastes good in soup.")
}
// Prints "Is it a spicy red pepper?"

case類型可以是String,這點比Objective-C方便很多,編程語言是給人讀的。

去掉default語句會報Switch must be exhaustive編譯錯誤,這是編程的實踐,避免開發者遺漏

未使用的變量_
let interestingNumbers = ["Prime": [2, 3, 5, 7, 11, 13],"Fibonacci": [1, 1, 2, 3, 5, 8],"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (_, numbers) in interestingNumbers {for number in numbers {if number > largest {largest = number}}
}
print(largest)

訪問for循環時沒有使用到字典的key,用_可以告訴編譯器這件事方便優化

// 如果非要定義了不用,會給一個警告
Immutable value 'key' was never used; consider replacing with '_' or removing it

函數和閉包

  1. 函數關鍵字 func
  2. -> 后跟返回值
  3. 函數定義對參數的聲明和objective-c類似
func greet(person: String, day: String) -> String {return "Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")

通過元組(tuple)可以處理多個值

func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {var min = scores[0]var max = scores[0]var sum = 0for score in scores {if score > max {max = score} else if score < min {min = score}sum += score}return (min, max, sum)
}
let statistics = calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
// Prints "120"
print(statistics.2)
// Prints "120"

嵌套函數

func returnFifteen() -> Int {var y = 10func add() {y += 5}add()return y
}
returnFifteen()

這個見的少,只見過類似概念的Java里的內部類

函數作返回值,參數

Functions are a first-class type. This means that a function can return another function as its value.

類型:規定了變量可以取的值得范圍,以及該類型的值可以進行的操作。根據類型的值的可賦值狀況,可以把類型分為三類:
1、一級的(first class)。該等級類型的值可以傳給子程序作為參數,可以從子程序里返回,可以賦給變量。大多數程序設計語言里,整型、字符類型等簡單類型都是一級的。
2、二級的(second class)。該等級類型的值可以傳給子程序作為參數,但是不能從子程序里返回,也不能賦給變量。
3、三級的(third class)。該等級類型的值連作為參數傳遞也不行。

函數當返回值

func makeIncrementer() -> ((Int) -> Int) {func addOne(number: Int) -> Int {return 1 + number}return addOne
}
var increment = makeIncrementer()
increment(7)

函數當參數

func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {for item in list {if condition(item) {return true}}return false
}
func lessThanTen(number: Int) -> Bool {return number < 10
}
var numbers = [20, 19, 7, 12]
// lessThanTen 函數作為參數
hasAnyMatches(list: numbers, condition: lessThanTen)

閉包

函數是一種特殊的閉包,有名字的閉包(closures)

// {} 內的是閉包
numbers.map({ (number: Int) -> Int inlet result = 3 * numberreturn result
})

簡化閉包寫法

省略return

let mappedNumbers = numbers.map({ number in 3 * number })
print(mappedNumbers)

當閉包是函數的唯一參數時,可以完全省略括號

let sortedNumbers = numbers.sorted { $0 > $1 }
print(sortedNumbers)

對象和類

class Shape {var numberOfSides = 0func simpleDescription() -> String {return "A shape with \(numberOfSides) sides."}
}

創建對象

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

初始化函數

class NamedShape {var numberOfSides: Int = 0var name: Stringinit(name: String) {self.name = name}func simpleDescription() -> String {return "A shape with \(numberOfSides) sides."}
}

子類重寫父類方法

class Square: NamedShape {var sideLength: Doubleinit(sideLength: Double, name: String) {self.sideLength = sideLengthsuper.init(name: name)numberOfSides = 4}func area() -> Double {return sideLength * sideLength}override func simpleDescription() -> String {return "A square with sides of length \(sideLength)."}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

屬性訪問器getter && setter

class EquilateralTriangle: NamedShape {var sideLength: Double = 0.0init(sideLength: Double, name: String) {self.sideLength = sideLengthsuper.init(name: name)numberOfSides = 3}var perimeter: Double {get {return 3.0 * sideLength}set {sideLength = newValue / 3.0}}override func simpleDescription() -> String {return "An equilateral triangle with sides of length \(sideLength)."}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)
// Prints "9.3"
triangle.perimeter = 9.9
print(triangle.sideLength)
// Prints "3.3000000000000003"

計算屬性

class TriangleAndSquare {var triangle: EquilateralTriangle {willSet {square.sideLength = newValue.sideLength}}var square: Square {willSet {triangle.sideLength = newValue.sideLength}}init(size: Double, name: String) {square = Square(sideLength: size, name: name)triangle = EquilateralTriangle(sideLength: size, name: name)}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
// Prints "10.0"
print(triangleAndSquare.triangle.sideLength)
// Prints "10.0"
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)
// Prints "50.0"

枚舉和結構體

enum Rank: Int {case ace = 1case two, three, four, five, six, seven, eight, nine, tencase jack, queen, kingfunc simpleDescription() -> String {switch self {case .ace:return "ace"case .jack:return "jack"case .queen:return "queen"case .king:return "king"default:return String(self.rawValue)}}
}
let ace = Rank.ace
let aceRawValue = ace.rawValue

rawValue 默認0開始,然后遞增

枚舉的 case 值是實際值,而不僅僅是編寫其原始值的另一種方式。事實上,在沒有有意義的原始值的情況下,可以不必提供原始值。

enum Suit {case spades, hearts, diamonds, clubsfunc simpleDescription() -> String {switch self {case .spades:return "spades"case .hearts:return "hearts"case .diamonds:return "diamonds"case .clubs:return "clubs"}}
}
let hearts = Suit.hearts
let heartsDescription = hearts.simpleDescription()

并發

異步方法的關鍵字 async,調用異步方法前面加await

func fetchUserID(from server: String) async -> Int {print("fetchUserID")if server == "primary" {return 97}return 501
}func fetchUsername(from server: String) async -> String {print("fetchUsername")let userID = await fetchUserID(from: server)if userID == 501 {return "John Appleseed"}return "Guest"
}func connectUser(to server: String) async {// 異步調用async let userID = fetchUserID(from: server)async let username = fetchUsername(from: server)// 等待返回后執行下一句let greeting = await "Hello \(username), user ID \(userID)"print(greeting)
}Task {await connectUser(to: "primary2")
}

等待任務組

let userIDs = await withTaskGroup(of: Int.self) { group infor server in ["primary", "secondary", "development"] {group.addTask {return await fetchUserID(from: server)}}var results: [Int] = []for await result in group {results.append(result)}return results
}

協議與擴展

使用關鍵字Protocol定義協議

protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()
}

類,枚舉和結構體都可以實現協議

class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."var anotherProperty: Int = 69105func adjust() {simpleDescription += "  Now 100% adjusted."}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescriptionstruct SimpleStructure: ExampleProtocol {var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

結構體的adjust方法前有mutating修飾用于修改結構體的成員

可以使用擴展來為已有的類型添加方法

extension Int: ExampleProtocol {var simpleDescription: String {return "The number \(self)"}mutating func adjust() {self += 42}}
print(7.simpleDescription)
// Prints "The number 7"

異常捕獲

通過實現Error協議來表示錯誤類型

enum PrinterError: Error {case outOfPapercase noTonercase onFire
}

throws 關鍵字來拋出異常

func send(job: Int, toPrinter printerName: String) throws -> String {if printerName == "Never Has Toner" {throw PrinterError.noToner}return "Job sent"
}

可以使用 do-catch 來捕獲異常,try 修飾可能會拋出異常的代碼

do {let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")print(printerResponse)
} catch {print(error)
}
// Prints "Job sent"

多種異常的處理

do {let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")print(printerResponse)
} catch PrinterError.onFire {print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {print("Printer error: \(printerError).")
} catch {print(error)
}
// Prints "Job sent"

defer關鍵詞修飾的代碼會在函數所有代碼執行完成后,函數return返回前執行。
無論代碼是否拋出異常都會執行。它一般用于建立或清理代碼。

有點類似finally 部分,可以避免異常的時候沒釋放內存。這在某個函數有多個返回出口的時候特別有用。

var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]func fridgeContains(_ food: String) -> Bool {fridgeIsOpen = truedefer {fridgeIsOpen = false}let result = fridgeContent.contains(food)return result
}
if fridgeContains("banana") {print("Found a banana")
}
print(fridgeIsOpen)

泛型

泛型: <類型>

func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {var result: [Item] = []for _ in 0..<numberOfTimes {result.append(item)}return result
}
makeArray(repeating: "knock", numberOfTimes: 4)

可以對方法,函數,類,枚舉,結構體應用泛型

// where T.Element: Equatable , T.Element == U.Element表示:只有元素遵循 Equatable 協議且內部的類型一致時才可以使用anyCommonElements方法
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Boolwhere T.Element: Equatable, T.Element == U.Element
{for lhsItem in lhs {for rhsItem in rhs {if lhsItem == rhsItem {return true}}}return false
}
anyCommonElements([1, 2, 3], [3])

參考

  1. Swift-Doc
  2. 什么是 First-class function?
  3. Swift系列之關于Swift defer的正確使用
  4. Swift限定泛型、協議擴展或約束的where

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

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

相關文章

確保連接器后殼高性能互連的完整性

本文探討了現代后殼技術如何促進高性能互連的電氣和機械完整性&#xff0c;以及在規范階段需要考慮的一些關鍵因素。 當今的航空航天、國防和醫療應用要求連接器能夠提供高速和緊湊的互連&#xff0c;能夠承受振動和沖擊&#xff0c;并保持對電磁和射頻干擾 &#xff08;EMI/R…

第IV部分有效應用程序的設計模式

第IV部分有效應用程序的設計模式 第IV部分有效應用程序的設計模式第23章:應用程序用戶界面的架構設計23.1設計考量23.2示例1:用于非分布式有界上下文的一個基于HTMLAF的、服務器端的UI23.3示例2:用于分布式有界上下文的一個基于數據API的客戶端UI23.4要點第24章:CQRS:一種…

學習筆記十四——一文看懂 Rust 迭代器

&#x1f300; 一文看懂 Rust 迭代器 &#x1f4da; 目錄導航 什么是迭代器&#xff1f;為什么 Rust 到處都在用它&#xff1f;Rust 迭代器的底層邏輯是什么&#xff1f;適配器 vs 消費者&#xff1a;誰是主角&#xff1f;常見適配器&#xff1a;加工數據的全能工廠常見消費者…

QR輕量二維碼生成系統PHP源碼

源碼介紹 基于PHP編寫的二維碼在線生成系統。只需點擊幾下就可以生成您的個人二維碼&#xff01;上傳您的徽標&#xff0c;選擇自定義顏色&#xff0c;生成多種類型。選擇一個圖案并下載最終的qrcode。可用格式&#xff1a;.png&#xff0c;.svg 效果預覽 源碼獲取 QR輕量二…

基于Spring MVC的客戶端真實IP獲取方案解析

文章目錄 基于Spring MVC的客戶端真實IP獲取方案解析概述核心方法解析代碼實現工作流程 IP獲取優先級策略IP有效性驗證異常處理與日志使用場景注意事項擴展建議 基于Spring MVC的客戶端真實IP獲取方案解析 概述 在Web應用開發中&#xff0c;準確獲取客戶端真實IP地址是常見的…

Idea集成AI:CodeGeeX開發

當入職新公司&#xff0c;或者調到新項目組進行開發時&#xff0c;需要快速熟悉項目代碼 而新的項目代碼&#xff0c;可能有很多模塊&#xff0c;很多的接口&#xff0c;很復雜的業務邏輯&#xff0c;更加有與之前自己的代碼風格不一致的現有復雜代碼 更別提很多人寫代碼不喜…

Python(18)Python中JSON的妙用:詳解序列化與反序列化原理及實戰案例

目錄 一、背景&#xff1a;為什么Python需要JSON&#xff1f;二、核心技術解析&#xff1a;序列化與反序列化2.1 核心概念2.2 類型映射對照表 三、Python操作JSON的四大核心方法3.1 基礎方法庫3.2 方法詳解1. json.dumps()2. json.loads()3. json.dump()4. json.load() 四、實戰…

【物聯網】基于LORA組網的遠程環境監測系統設計

基于LORA組網的遠程環境監測系統設計 演示視頻: 簡介: 1.本系統有一個主機,兩個從機。 2.一主多從的LORA組網通信,主機和兩個從機都配備了STM32F103單片機與 LoRa 模塊,主機作為中心設備及WIFI網關,負責接收和發送數據到遠程物聯網平臺和手機APP,兩個從機則負責采集數…

通過金融科技(Fintech)掌控財務:智能理財管理指南

李升偉 編譯 在當今世界&#xff0c;科技幾乎重塑了我們生活的方方面面&#xff0c;包括金錢的管理方式。金融科技&#xff08;Fintech&#xff09;讓個人財務管理變得前所未有的便捷、高效和智能。從追蹤支出到投資理財、提升信用評分&#xff0c;金融科技工具賦予個人掌控財…

html-css樣式

1. 所有類型為文本的 元素的樣式 指定所有類型為文本的 元素的樣式 /* 文本框的樣式 */ input[type"text"] { font-size: 25px;width: 80px; /* 文本框的寬度 */ padding: 25px; } font-size&#xff1a;字體大小 width&#xff1a;文本框寬度 padding&#…

【C語言基礎】C++ 中的 `vector` 及其 C 語言實現詳解

一、C 中的 vector&#xff1a;動態數組的核心特性 1. 基本概念 vector 是 C 標準模板庫&#xff08;STL&#xff09;中的動態數組容器&#xff0c;支持自動擴容、高效元素訪問和豐富的操作接口。其核心特性包括&#xff1a; 動態內存管理&#xff1a;自動調整容量&#xff0…

nvm切換node版本后,解決npm找不到的問題

解決方法如下 命令行查看node版本 node -v找到node版本所對應的npm版本 點擊進入node版本 npm對應版本下載 點擊進入npm版本 下載Windows 壓縮包 下載完成后&#xff0c;解壓&#xff0c;文件改名為npm 復制到你nvm對應版本的node_modules 下面 將下載的npm /bin 目錄…

數據結構:最小生成樹的普里姆算法和克魯斯卡爾算法

對于一個帶權&#xff08;假設每條邊上的權均為大于零的實數&#xff09;連通無向圖 G 中的不同生成樹&#xff0c;其每棵樹的所有邊上的權值之和也可能不同&#xff1b;圖的所有生成樹中具有邊上的權值之和最小的樹稱為圖的最小生成樹&#xff08;Minimal Spanning Tree&#…

Information-Theoretic Limits of Bistatic Integrated Sensing and Communication

摘要 雙靜態感知指的是發射器&#xff08;照亮目標&#xff09;和感知接收器&#xff08;估計目標狀態&#xff09;在物理上分離的場景&#xff0c;這與發射和感知功能共存的單靜態感知形成對比。在實際場景中&#xff0c;雙靜態感知可能需要應對系統約束&#xff0c;或者作為…

XCTF-web(四)

unserialize3 需要反序列化一下&#xff1a;O:4:“xctf”:2:{s:4:“flag”;s:3:“111”;} php_rce 題目提示rce漏洞&#xff0c;測試一下&#xff1a;?s/Index/\think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]1 flag&#xff1…

Java Stream深度解析 高階技巧與性能優化實戰

文章目錄 一、Stream底層機制揭秘1.1 Stream流水線架構1.2 Spliterator探秘 二、自定義收集器高級實現2.1 實現高性能統計收集器2.2 多級分組優化技巧 三、并行流深度優化3.1 并行度控制策略3.2 工作竊取(Work-Stealing)優化 四、無限流與短路操作4.1 生成無限質數流4.2 短路操…

TailwindCss快速上手

什么是Tailwind Css? 一個實用優先的 CSS 框架&#xff0c;可以直接在標記中組合以構建任何設計。 開始使用Tailwind Css 如何安裝 下面是使用vite構建工具的方法 ①安裝 Tailwind CSS: tailwindcss通過tailwindcss/vitenpm安裝。 npm install tailwindcss tailwindcss…

Web前端 (CSS篇)

什么是CSS&#xff1f; css(Cascading Style Sheets)是層疊樣式表或級聯樣式表&#xff0c;是一組設置規則&#xff0c;用于控制web頁面外觀。 為什么使用CSS? CSS 用于定義網頁的樣式&#xff0c;包括針對不同設備和屏幕尺寸的設計和布局。 CSS 實例 body {background-col…

微服務2--服務治理與服務調用

前言 &#xff1a;本文主要闡述微服務架構中的服務治理&#xff0c;以及Nacos環境搭建、服務注冊、服務調用&#xff0c;負載均衡以及Feign實現服務調用。 服務治理 服務治理是微服務架構中最核心最基本的模塊。用于實現各個微服務的自動化注冊與發現。 服務注冊&#xff1a;在…

智能麻將出牌組件

開篇引言? 麻將作為一款風靡全球的策略性游戲&#xff0c;其復雜的規則和多變的牌局給玩家帶來了無盡樂趣。在數字化時代&#xff0c;運用編程技術為麻將游戲賦予智能&#xff0c;實現自動出牌功能&#xff0c;不僅能提升玩家體驗&#xff0c;還能深入探索算法在博弈游戲中的…