Swift入門筆記

Swift入門筆記

  • 簡單值
  • 控制流
  • 函數和閉包
  • 對象和類
  • 枚舉和結構體
  • 并發
  • 協議和擴展
  • 錯誤處理
  • 泛型

簡單值

// 聲明變量
var myVariable = 42
myVariable = 50
// 聲明常量
let myConstant = 42
// 聲明類型
let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
// 顯式類型轉換
let label = "The width is "
let width = 94
let widthLabel = label + String(width)
// 字符串中轉換
let apples = 3
let appleSummary = "I have \(apples) apples"
// 多行內容
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 wscaped.I still have \(apples) pieces of fruit."""
// 創建數組
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
// 創建字典
var occupations = ["Malcolm": "Captain","Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
// 數組添加元素
shoppingList.append("blueberries")
// 使用初始化器語法來創建一個空的數組
let emptyArray = [String]()
// 使用初始化器語法來創建一個空的字典
let emptyDictionary = [String: Float]()
// 如果類型信息能被推斷(變量設置新的值或者傳參數給函數)
shoppingList = []
occupations = [:]

控制流

// 控制流,if語句當中,條件必須是布爾表達式,不再隱式地與零做計算
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {if score > 50 {teamScore += 3} else {teamScore += 1}
}
// 等于符號賦值或者 return  后使用 if  或者 switch
let scoreDecoration =if teamScore > 10 {"🎉"} else {""}
// ?把某個值標記為可選的
var optionalString: String? = "Hello"
// if-let操作那些可能會丟失的值,
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {greeting = "Hello, \(name)"
}
// ??提供默認值
let nickName: String? = nil
let fullName: String = "John Appleseed"
let informalGreeting = "Hi \(nickName ?? fullName)"
// 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.")
}
// for-in遍歷字典
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}}
}
// while
var n = 2
while n < 100 {n = n * 2
}
var m = 2
repeat {m = m * 2
} while m < 100
// ..創造序列區間
var total = 0
for i in 0..<4 {total += i
}

函數和閉包

// func聲明函數
func greet(person: String, day: String) -> String {return "Hello \(person), today is \(day)"
}
var s = greet(person: "Bob", day: "Tuesday")
// 默認使用形參作為實參,可以在形參前自定義實參名或者使用_避免使用實參
func greet(_ person: String, on day: String) -> String {return "Hello \(person), today is \(day)"
}
s = greet("John", on: "Wednesday")
// 使用元祖來創建復合值
func calculateStatics(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 = calculateStatics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
print(statistics.2)
// 函數接受多個參數存放在數組中
func sumOf(numbers: Int...) -> Int {var sum = 0for number in numbers {sum += number}return sum
}
var i = sumOf()
i = sumOf(numbers: 42, 597, 12)
// 內嵌函數可以訪問外部函數里的變量
func returnFifteen() -> Int {var y = 10func add() {y += 5}add()return y
}
i = returnFifteen()
// 函數是一等類型,函數可以把函數作為值來返回
func makeIncrementer() -> ((Int) -> Int) {func addOne(number: Int) -> Int {return 1 + number}return addOne
}
var increment = makeIncrementer()
i = 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]
var b = hasAnyMatches(list: numbers, condition: lessThanTen)
// 閉包中用in分割實際參數和返回類型
var a = numbers.map({(number: Int) -> Int inlet result = 3 * numberreturn result
})
// 閉包類型已知,可以去掉參數類型和返回類型
let mappedNumbers = numbers.map({ number in 3 * number})
print(mappedNumbers)
// 通過數字調用參數,當閉包時最后一個參數時,可以直接跟在圓括號后邊。如果閉包是唯一參數,可以去掉圓括號。
let sortedNumbers = numbers.sorted { $0 > $1 }

對象和類

// 創建類
class Shape {var numberOfSides = 0func simpleDescription() -> String {return "A shape with \(numberOfSides) sides."}
}
// 創建實例,訪問實例的屬性和方法
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
// 初始化器
class NameShape {var numberOfSides: Int = 0var name: Stringinit(name: String) {self.name = name}func simpleDescription() -> String {return "A shape with \(numberOfSides) sides."}
}
// 子類重寫父類的實現
class Square: NameShape {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")
var d = test.area()
s = test.simpleDescription()
// 計算屬性
class EquilateralTriangle: NameShape {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)."}
}
// 在設置一個新值前后執行代碼
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)}
}
// 如果?前面的值是nil,那?后的所有內容都會被忽略并且整個表達式的值都是nil。否則,可選項的值將被展開,然后?后邊的代碼根據展開的值執行
let optionalSquare: Square? = Square(sideLength: 2.5, name:"optional square")
let sideLength = optionalSquare?.sideLength

枚舉和結構體

// 枚舉,默認從零開始給原始值賦值后邊遞增,可以通過制定特定的值來改變
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
// 使用init?(rawValue)初始化器從原始值創建枚舉實例
if let convertedRank = Rank(rawValue: 3) {let threeDescription = convertedRank.simpleDescription()print(threeDescription)
}
// 枚舉成員的值是實際的值
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()
// case與值關聯,值在初始化實例的時候確定,這樣它們就可以在每個實例中不同了
enum ServerResponse {case result(String, String)case failure(String)
}
let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")
switch success {case let .result(sunrise, sunset):print("Sunrise is at \(sunrise) and sunset is at \(sunset)")case let .failure(message):print("Failure... \(message)")
}
// 結構體在傳遞的時候拷貝其自身,而類會傳遞引用
struct Card {var rank: Rankvar suit: Suitfunc simpleDescription() -> String {return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"}
}
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

并發

// async標記異步執行的函數
func fetchUserID(from server: String) async -> Int {if server == "primary"{return 97}return 501
}
// await標記對異步函數的調用
func fetchUsername(from server: String) async -> String {let userID = await fetchUserID(from: server)if userID == 501 {return "John Appleseed"}return "Guest"
}
// async let可讓它與其他異步函數并行執行,當要用返回值時,再使用await
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: "primary")
}
// 使用任務組來構造并發代碼
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
}
print(userIDs)
// 執行者確保不同異步函數可以在同一時間安全地與同一個執行者的實例進行交互
actor ServerConnection {var server: String = "primary"private var activeUsers: [Int] = []func connect() async -> Int {let userID = await fetchUserID(from: server)activeUsers.append(userID)return userID}
}
// 調用執行者的方法或屬性時,要用await標記代碼以表明它可能需要等待其他正在訪問的代碼結束
let server = ServerConnection()
let userID = await server.connect()

協議和擴展

// protocol聲明協議
protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()
}
// 類、枚舉以及結構體都兼容協議,mutating關鍵字來聲明使方法可以修改結構體,類中不需要這樣聲明
class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."var anothorProperty: Int = 69105func adjust() {simpleDescription += " Now 100% adjusted."}
}
var aa = SimpleClass()
aa.adjust()
let aDescription = aa.simpleDescriptionstruct SimpleStructure: ExampleProtocol {var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"}
}
var bb = SimpleStructure()
bb.adjust()
let bDescription = bb.simpleDescription
// 使用extension來給現存的類型增加功能
extension Int: ExampleProtocol {var simpleDescription: String {return "The number \(self)"}mutating func adjust() {self += 42}
}
print(7.simpleDescription)
// 當操作類型是協議類型的值的時候,協議外定義的方法是不可用的
let protocolValue: ExampleProtocol = aa
print(protocolValue.simpleDescription)
// print(protocolValue.anothorProperty)

錯誤處理

// 用任何遵循Error協議的類型來表示錯誤
enum PrinterError: Error {case outOfPapercase noTonercase onFire
}
// 使用throw來拋出錯誤并且用throws標記一個可以拋出錯誤的函數。如果在函數里拋出一個錯誤,函數會立即返回并且調用函數的代碼處理錯誤
func send(job: Int, toPrinter printerName: String) throws -> String {if printerName == "Never Has Toner" {throw PrinterError.noToner}return "Job sent"
}
// 用do-catch處理錯誤。在do代碼里,用try來在能拋出錯誤的函數前標記。在catch代碼塊,如果不給定其他名字,錯誤會自動賦予名字error。
do {let printResponse = try send(job: 1040, toPrinter: "Bi Sheng")print(printResponse)
} catch {print(error)
}
// 提供多個catch代碼塊來處理特定的錯誤,用法和switch里的case一樣
do {let printResponse = try send(job: 1440, toPrinter:"Gutenberg")print(printResponse)
} 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)
}
// 使用try?來轉換結果為可選項。如果函數拋出了錯誤,那么錯誤被忽略并且結果為nil。否則,結果是一個包含了函數返回值的可選項
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")
// 使用defer來寫函數返回后也會被執行的代碼,無論是否錯誤被拋出。甚至可以在沒有任何錯誤處理的時候使用defer,來簡化需要在多處地方返回的函數。
var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]
func fridgeContains(_ food: String) -> Bool {fridgeIsOpen = truedefer {fridgeIsOpen = false}print(fridgeIsOpen)let result = fridgeContent.contains(food)return result
}
b = fridgeContains("banana")
print(fridgeIsOpen)

泛型

// 創建一個泛型方法或者類型
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {var result = [Item]()for _ in 0..<numberOfTimes {result.append(item)}return result
}
var aes = makeArray(repeating: "knock", numberOfTimes:4)
print(aes)
// 可以從函數、方法、類、枚舉、結構體創建泛型
enum OptionalValue<Wrapped> {case nonecase some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)
// 類型名稱后緊接where來明確一系列需求
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Boolwhere T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element {for lhsItem in lhs {for rhsItem in rhs {if lhsItem == rhsItem {return true}}}return false}b = anyCommonElements([1, 2, 3], [3])print(b)

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

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

相關文章

排序相關算法--3.選擇排序

之前涉及的堆排序就是選擇排序的一種&#xff0c;先進行選擇。 基本選擇排序&#xff1a; 最簡單&#xff0c;也是最沒用的排序算法&#xff0c;時間復雜度高并且還是不穩定的排序方法&#xff0c;項目中很少會用。 過程&#xff1a; 在一個長度為 N 的無序數組中&#xff0c;…

智慧公廁系統助力城市衛生管理

在當今快速發展的城市環境中&#xff0c;城市衛生管理面臨著諸多挑戰。其中&#xff0c;公共廁所的管理一直是一個重要但又常被忽視的環節。然而&#xff0c;隨著科技的不斷進步&#xff0c;智慧公廁系統的出現為城市衛生管理帶來了全新的解決方案&#xff0c;成為提升城市品質…

OrangePi AIpro 淺上手

OrangePi AIpro 淺上手 OrangePi AIpro 介紹開發版介紹硬件規格頂層視圖和底層視圖接口詳情圖 玩轉 OrangePi AIPro燒錄鏡像串口調試連接 WiFissh 連接配置下載源 使用感受優點&#xff1a;缺點或需注意的點&#xff1a; OrangePi AIpro 介紹 開發版介紹 OrangePi AIpro是香橙…

【大語言模型】私有化搭建-企業知識庫-知識問答系統

下面是我關于大語言模型學習的一點記錄 目錄 人工智能學習路線 MaxKB 系統(基于大語言模型的知識問答系統) 部署開源大語言模型LLM 1.CPU模式(沒有好的GPU&#xff0c;算力和效果較差) 2.GPU模式&#xff08;需要有NVIDIA顯卡支持&#xff09; Ollama網絡配置 Ollama前…

【問卷系統】TDucKX更新速覽

TDuck是一款在線表單問卷收集工具&#xff0c;開源地址&#xff1a;https://gitee.com/TDuckApp一款免費的表單問卷系統&#xff1b;可快速創建問卷或業務表單&#xff0c;采用無代碼理念支持開發自定義組件。采用SpringBootVueElementUI技術棧&#xff0c;功能強大界面清新&am…

Catena-x標準解讀:CX-0007 Minimal Data Provider Service Offering v1.0.2 最小數據提供商服務產品

為了更好地理解&#xff0c;最小數據提供者服務也將被稱為“上傳工具”。 對于數據供應工具來說&#xff0c;數據主權的概念尤為重要。數據主權是Catena-X網絡的核心價值觀之一。每個參與者都應該盡可能多地控制自己的數據。這包括 他總是確切地知道他在與誰交換數據。參與者…

【GameFramework擴展應用】6-4、GameFramework框架增加AB包加解密功能

推薦閱讀 CSDN主頁GitHub開源地址Unity3D插件分享簡書地址QQ群:398291828大家好,我是佛系工程師☆恬靜的小魔龍☆,不定時更新Unity開發技巧,覺得有用記得一鍵三連哦。 一、前言 【GameFramework框架】系列教程目錄: https://blog.csdn.net/q764424567/article/details/1…

軟件測試面試200問(全)

1、B/S架構和C/S架構區別 B/S 只需要有操作系統和瀏覽器就行&#xff0c;可以實現跨平臺&#xff0c;客戶端零維護&#xff0c;維護成本低&#xff0c;但是個性化能力低&#xff0c;響應速度較慢 C/S響應速度快&#xff0c;安全性強&#xff0c;一般應用于局域網中&#xff0…

【matlab】智能優化算法優化BP神經網絡

目錄 引言 一、BP神經網絡簡介 二、智能優化算法概述 三、智能優化算法優化BP神經網絡的方法 四、蜣螂優化算法案例 1、算法來源 2、算法描述 3、算法性能 結果仿真 代碼實現 引言 智能優化算法優化BP神經網絡是一個重要的研究領域&#xff0c;旨在通過智能算法提高…

變量篩選—特征包含信息量

在變量篩選中,通過衡量特征所包含信息量大小,決定是否刪除特征,常用的指標有單一值占比、缺失值占比和方差值大小。單一值或缺失值占比越高,表示特征包含信息量越少,不同公司設置不同閾值,一般單一值、缺失值占比高于95%,建議刪除。方差值越小,代表特征包含信息量越小。…

入職前回顧一下git-01

git安裝 Linux上安裝git 在linux上建議用二進制的方式來安裝git&#xff0c;可以使用發行版包含的基礎軟件包管理工具來安裝。 紅帽系 sudo yum install gitDebian系 sudo apt install gitWindows上安裝git 去官網下載和操作系統位數相同的安裝包.或者可以直接安裝GitHub…

模板引擎是什么?

模板引擎&#xff08;Template Engine&#xff09;是一種用于生成文本輸出的工具&#xff0c;尤其在Web開發中應用廣泛。它的主要目的是將用戶界面&#xff08;通常是HTML等模板文件&#xff09;與業務數據&#xff08;內容&#xff09;分離&#xff0c;從而提供一種高效、靈活…

[圖解]SysML和EA建模住宅安全系統-14-黑盒系統規約

1 00:00:02,320 --> 00:00:07,610 接下來&#xff0c;我們看下一步指定黑盒系統需求 2 00:00:08,790 --> 00:00:10,490 就是說&#xff0c;把這個系統 3 00:00:11,880 --> 00:00:15,810 我們的目標系統&#xff0c;ESS&#xff0c;看成黑盒 4 00:00:18,030 --> …

spring管理bean源碼解析

1. 從啟動類開始 public static void main(String[] args) {// Run the SpringApplication class with the Application class as the first argumentSpringApplication.run(Application.class, args);}2. bean 實例化 // SpringAplication row1294,1295 run() // SpringApli…

Power Apps使用oData訪問表數據并賦值前端

在使用OData查詢語法通過Xrm.WebApi.retrieveMultipleRecords方法過濾數據時&#xff0c;你可以指定一個OData $filter 參數來限制返回的記錄集。 以下是一個使用Xrm.WebApi.retrieveMultipleRecords方法成功的例子&#xff0c;它使用了OData $filter 參數來查詢實體的記錄&am…

【Parallel SSH】Ubuntu系統配置pssh實現多主機并行執行Master分發的命令

文章目錄 一、配置多機免密登錄二、ubuntu系統安裝pssh三、并行命令腳本編寫 一、配置多機免密登錄 假設有1臺主機作為Master分發命令&#xff0c;3臺主機作為Servers執行命令。假設Master主機內網IP地址為192.168.0.12&#xff0c;Servers外網IP及對應的hostname分別為&#…

最新盤點!2024年最值得了解的24款項目管理軟件

一、企業該如何選擇一款項目管理工具&#xff1f;選擇項目管理工具時需要考慮哪些因素&#xff1f; 在選擇和對比項目管理工具時&#xff0c;可以通過加權方式進行對比和評估。參考以下模板&#xff0c;可以把自己關注的項目管理工具&#xff0c;進行表格對比&#xff0c;選中…

企業智能制造賦能的環境條件為什么重要?需要準備什么樣的環境?

在全球制造業不斷演進的今天&#xff0c;智能制造已經成為推動行業創新和轉型的關鍵力量。它不僅代表了技術的革新&#xff0c;更是企業管理模式和運營思路的全面升級。然而&#xff0c;智能制造的落地實施并非一蹴而就&#xff0c;它需要企業在環境條件上做好充分的準備&#…

jail內部ubuntu apt升級失敗問題解決-Dynamic MMap ran out of room

在FreeBSD jail 里安裝啟動Ubuntu jammy系統&#xff0c;每次裝好執行jexec ubjammy sh進入Ubuntu系統后&#xff0c;執行apt update報錯。 這個問題困惑了好久&#xff0c;突然有一天仔細去看報錯信息&#xff0c;查看了(man 5 apt.conf) &#xff0c;才搞定問題。簡單來說就是…

Mybatis攔截器介紹及其應用

Mybatis攔截器介紹及其應用 1、介紹 Mybatis攔截器設計的初衷就是為了供用戶在某些時候可以實現自己的邏輯而不必去動Mybatis固有的邏輯。通過Mybatis攔截器我們可以攔截某些方法的調用&#xff0c;我們可以選擇在這些被攔截的方法執行前后加上某些邏輯&#xff0c;也可以在執…