洪敏菖
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ###### tags: `App Developer行動開發工程師養成班` Swift語法基礎 === ### 9X9(一行) 使用while用法 ```swift= var mt : Int var chenSue : Int //乘數 var product : Int // 積 mt = 1 // 被乘數 chenSue = 1 while chenSue <= 9 { product = mt * chenSue print( "(\(mt)*\(chenSue)=" , terminator:"") if product < 10 { print("0", terminator:"") } print("\(product))" , terminator:"") chenSue += 1 } ``` ``` (1*1=01)(1*2=02)(1*3=03)(1*4=04)(1*5=05)(1*6=06)(1*7=07)(1*8=08)(1*9=09) ``` ### 9X9(一行) 使用 for...in「stride」(from..through/to..by)用法 ##### 「stride」 代表 決定 for in 語法的數字範圍 ##### 「from」 代表 開始的數字 ##### 「through」代表 結束的數字 ,through 的數字將被包含 ##### 「to」代表 結束的數字, to 的數字將不被包含 ```swift= for cs in stride(from: 1, through: 9, by: 1) { let mt = 7 let product = mt * cs print("(\(mt)X\(cs)=\( product<10 ? "0":"")\(product))" , terminator:"") } print() ``` ``` 7X1=07)(7X2=14)(7X3=21)(7X4=28)(7X5=35)(7X6=42)(7X7=49)(7X8=56)(7X9=63) ``` ### 9X9(一行) 使用dot.dot.dot與三元運算子用法 ```swift= // dot.dot.dot for cs in 1...9 { let mt = 5 let product = mt * cs print("(\(mt)X\(cs)=\( product < 10 ? "0": "")\(product))" ,terminator: "") } print() ``` ``` (5X1=05)(5X2=10)(5X3=15)(5X4=20)(5X5=25)(5X6=30)(5X7=35)(5X8=40)(5X9=45) ``` ### 9X9(一行) 使用repeat...while用法 ```swift= var cs = 1 repeat { let mt = 8 let product = mt * cs print("(\(mt)X\(cs)=\( product < 10 ? "0": "")\(product))" ,terminator: "") cs += 1 } while cs <= 9 print() ``` ``` (8X1=08)(8X2=16)(8X3=24)(8X4=32)(8X5=40)(8X6=48)(8X7=56)(8X8=64)(8X9=72) ``` ### 定義類別,並在主程式引用執行 ```swift= class func theWriteNineAline ( 被乘數 multiplicant : Int ) { for chenShu in 1...9 { let product = multiplicant * chenShu print("(\(multiplicant)x\(chenShu)=", terminator: "" ) if product < 10 { print("0", terminator: "" ) } print("\(product))", terminator: "" ) } } override func viewDidLoad() { super.viewDidLoad() // fix 練習 #1 如何改成執行時會印出 九九乘法 // fix 練習 #0 觀察執行會如何? for cs in 1...9 { ViewController.theWriteNineAline(被乘數: cs) print() } } ``` ### ternary 三元運算子 ```swift= var x = "unknown" var p = 9 x = p < 10 ? "=0" : "0" print(x) print("p = 23") p = 23 x = p < 10 ? "=0" : "0" print(x) ``` ``` =0 p = 23 0 ``` ### switch case 加上where,增加條件限制 ```swift= for x in 5...14 { print("x 為 \(x)") switch x { case 7...13 where x % 2 == 1 : print("為 7 或者 9 或者 11 或者 13") print() default : print(" x 不等於 6 , 7 , 9 , 11 而且 也不等於 13") print() } } ``` ``` x 為 5 x 不等於 6 , 7 , 9 , 11 而且 也不等於 13 x 為 6 x 不等於 6 , 7 , 9 , 11 而且 也不等於 13 x 為 7 為 7 或者 9 或者 11 或者 13 x 為 8 x 不等於 6 , 7 , 9 , 11 而且 也不等於 13 x 為 9 為 7 或者 9 或者 11 或者 13 x 為 10 x 不等於 6 , 7 , 9 , 11 而且 也不等於 13 x 為 11 為 7 或者 9 或者 11 或者 13 x 為 12 x 不等於 6 , 7 , 9 , 11 而且 也不等於 13 x 為 13 為 7 或者 9 或者 11 或者 13 x 為 14 x 不等於 6 , 7 , 9 , 11 而且 也不等於 13 ``` ### 座標 switch case 不加上where用法 ```swift= var 座標 : ( x : Int , y : Int) for cs in 0...3 { 座標.x = cs % 2 //取餘數 座標.y = cs / 2 //取整數 print("座標 為 (\(座標.x) , \(座標.y)) " ) switch 座標 { case (0,0): print("是原點") case (0,_): print("不是原點,但是在垂直軸上") case (_,0): print("不是原點,但是在水平軸上") default: print("不是原點,也不在垂直軸上,也不在水平軸上") } print("\n") } print() ``` ``` 座標 為 (0 , 0) 是原點 座標 為 (1 , 0) 不是原點,但是在水平軸上 座標 為 (0 , 1) 不是原點,但是在垂直軸上 座標 為 (1 , 1) 不是原點,也不在垂直軸上,也不在水平軸上 ``` ### 座標 switch case 加上「where」 用法 ```swift= for se in 0...3 { 座標.x = se % 2 座標.y = se / 2 print("座標 為 ( \( 座標.x ) , \( 座標.y ) )") print() // fix 練習 #1 // 觀察下面 switch 判斷語法 switch 座標 // 由上而下, ㄧㄧ比對 { case ( 0 , _ ) where 座標.y != 0 : print(" 落在垂直軸 而 y 等於 \(座標.y) , 但不是原點") case ( _ , 0 ) where 座標.x != 0 : print(" 落在水平軸 而 x 等於 \(座標.x) , 但不是原點") case ( 0 , 0 ) : print(" 是原點") default : print(" 座標 不是原點 而且 不在垂直軸 也不在水平軸") print() } } ``` ``` 座標 為 ( 0 , 0 ) 是原點 座標 為 ( 1 , 0 ) 落在水平軸 而 x 等於 1 , 但不是原點 座標 為 ( 0 , 1 ) 落在垂直軸 而 y 等於 1 , 但不是原點 座標 為 ( 1 , 1 ) 座標 不是原點 而且 不在垂直軸 也不在水平軸 ``` ### while 與 break/ continue 的用法 ```swift= var x = 0 var y = 0 print ("B1002 rooom") Nick : while y < 9 { x = 0 while x <= 4 { x += 1 if x == 4 { break //Nick//continue } print("\(x)" , terminator:" ") } print() print(" y 是 \(y)" ) y += 1 } print("MAPD35") ``` ``` ######break######## B1002 rooom 1 2 3 y 是 0 1 2 3 y 是 1 1 2 3 y 是 2 1 2 3 y 是 3 1 2 3 y 是 4 1 2 3 y 是 5 1 2 3 y 是 6 1 2 3 y 是 7 1 2 3 y 是 8 MAPD35 ``` ``` ######break Nick 整個迴圈程式結束######## B1002 rooom 1 2 3 MAPD35 ``` ``` ######continue######## B1002 rooom 1 2 3 5 y 是 0 1 2 3 5 y 是 1 1 2 3 5 y 是 2 1 2 3 5 y 是 3 1 2 3 5 y 是 4 1 2 3 5 y 是 5 1 2 3 5 y 是 6 1 2 3 5 y 是 7 1 2 3 5 y 是 8 MAPD35 ``` ### 型態方法 ```swift= // fix 練習 #0-1 觀察下面發明了ㄧ個 type method // (翻譯成中文 為 型態方法) // 此'型態方法'名稱為 theOdd class func theOdd ( // fix 練習 #0-2 觀察小括弧內為 參數宣告 // 此參數 名稱為 target 其型態為 Int 就是整數 // fix 練習 #0-6 觀察 // Int2detect 為此參數 target 的外部名稱 Int2detect target : Int) -> Bool // fix 練習 #0-4 此方法的身體由 大括弧 { 開始 { let 答案 : Bool // fix 練習 #0-3 此名稱為 target 的參數 // 可在此方法的身體內被使用, 如下行 target % 2 let 餘數 : Int = target % 2 答案 = 餘數 == 1 return 答案 }// fix 練習 #0-5 此方法的身體在 大括弧 } 結束 override func viewDidLoad() { super.viewDidLoad() for 實際參數 in 2...5 { let 是奇數 : Bool // fix 練習 #0-7 觀察 // Int2detect 為此參數 target 的外部名稱 // '外部名稱' 可以讓呼叫這個method的程式設計師 // 比較能夠知道這個參數的意義. // fix 練習 #0-8 觀察 // 讓呼叫這個 '型態方法' 的語法為 '型態名稱'.'型態方法名稱' (參數) 是奇數 = ViewController.theOdd ( Int2detect : 實際參數 ) print( "\(實際參數) 是 \( 是奇數==false ? "偶數" : "奇數" ) " ) } print() } ``` ``` 2 是 偶數 3 是 奇數 4 是 偶數 5 是 奇數 ``` ### 類型方法 ```swift= class 存款帳號 { class func print利率() { // print("餘額 為 \(餘額)") print("百分之 \"3.8\" ") } var 餘額 : Double = 100 func isVIP () -> Bool { return 餘額 >= 10000000 } } class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // print("新產品") // 存款帳號.print利率() var 郭昌明的帳戶 : 存款帳號 //宣告變數 郭昌明的帳戶 = 存款帳號() //指定參考值 var 是貴賓 = 郭昌明的帳戶.isVIP() print("是貴賓 為 \(是貴賓)") // 執行class func print("查完了") 郭昌明的帳戶.餘額 = 200000000 是貴賓 = 郭昌明的帳戶.isVIP() print("是貴賓 為 \(是貴賓)") print() } } ``` ``` 是貴賓 為 false 查完了 是貴賓 為 true ``` ### 兩個問號 - ?? 如果某個變數可能是nil時,可以使用??來給予一個預設值 ```swift= print("MAPD35 在 B1002 教室" ) print("var pN : Int? = nil ") // fix 練習 #0 觀察下行 pN 變數 的資料型態是 Int? var pN : Int? = nil // fix 練習 #1 您想寫出ㄧ個效果: // 若 pN == nil 則 pN 存 0 的值, 否則不用改變 pN 所存的值 pN = pN ?? 0 // 看 pN 所存的 Int 的值 print( pN! ) print() print("pN = -5 ") pN = -5 pN = pN ?? 0 print( pN! ) print() print() print("var PS : Int? = nil ") // fix 練習 #2 觀察下行 PS 變數 的資料型態是 Int! var PS : Int! = nil // fix 練習 #3 您想寫出ㄧ個效果: // 若 PS == nil 則 PS 存 6 的值, 否則不用改變 PS 所存的值 PS = PS ?? 6 // 看 PS 所存的 Int 的值 加 200 的和 print( PS + 200 ) print() PS = -300 PS = PS ?? 6 //沒有取6的值了,抓到-300 print( PS + 200 ) ``` ``` MAPD35 在 B1002 教室 var pN : Int? = nil 0 pN = -5 -5 var PS : Int? = nil 206 -100 ``` ### 變數指派預設值,如果有再指派新的值,會以新的執行結果 ```swift= // fix 練習 #0 以下程式碼是要做出數學分數的相關教學App var son0 : Int = 2//這代表一個分數(我們姑且叫做分數 A )的分子 var mom0 : Int = 5//這代表一個分數(我們姑且叫做分數 A )的分母 son0 = 3 mom0 = 11 // 印出一個分數(我們姑且叫做分數 A )的表示式: 分子/分母 print("A 為 \( son0 )/\( mom0 )" ) var son1 :Int = 2// 這代表另一個分數(我們姑且叫做分數 B )的分子 var mom1 :Int = 5// 這代表另一個分數(我們姑且叫做分數 B )的分母 son1 = 13 mom1 = 7 // 印出另一個分數(我們姑且叫做分數 B )的表示式: // 分數B的分子/分數B的分母 print("B 為 \( son1 )/\( mom1 )" ) ``` ``` A 為 3/11 B 為 13/7 ``` ### 字典dictionary ```swift= var sz : Int // fix 練習 #0 觀察下行 [ String : Int ] 為 字典 型態 // 字典: 為擁有「鍵」 搭配「值」 的成對組 存在其中的容器 // key(翻譯成 鍵 ) 的資料型態為 String // value(翻譯成 值 ) 的資料型態為 Int // 下行 [ : ] 代表空的字典, 也就是 「鍵」 搭配 「值」的成對組 , 連 1 組 都沒有 var dk : [ String : Int ] = [ : ] // count 代表 字典有幾對(或是幾組) key value 配對 sz = dk.count print(" dk.count 為 \(dk.count)") // 下行 dk ["ktm"] 代表 想以鍵是 "ktm" 查出搭配 的值 // , 值的型態是 Int 整數, 但須注意不ㄧ定有這樣的成對組 // , 字典目前有 0 對 // , 用 dk ["ktm"] 語法, 不ㄧ定可查出任何值 // , 所以 dk ["ktm"] 是 Int? 資料型態 let pv : Int? = dk ["ktm"] if let vu : Int = pv { print(" vu 為 \(vu)") } else { print(" dk [\"ktm\"] == nil 為 \( dk ["ktm"] == nil )") } // 下行 代表 鍵是 "ktm" 搭配 值是 9 的成對組 dk ["ktm"] = 9 print( " dk [\"ktm\"] = 9 " ) print( " dk.count 為 \(dk.count)") if let vu = dk ["ktm"] { print(" vu 為 \(vu)") } else { print(" dk [\"ktm\"] == nil 為 \( dk ["ktm"] == nil )") } // 下行 代表 鍵是 "ktm" 搭配 值是 28 的成對組 dk ["ktm"] = 28 print( " dk [\"ktm\"] = 28 " ) print( " dk.count 為 \(dk.count)") if let vu = dk ["ktm"] { print(" vu 為 \(vu)") } else { print(" dk [\"ktm\"] == nil 為 \( dk ["ktm"] == nil )") } // 下行 代表要從字典移除 鍵是 "ktm" 搭配的值 的成對組 dk.removeValue(forKey: "ktm") print( " dk [\"ktm\"] = 28 " ) print( " dk.count 為 \(dk.count)") if let vu = dk ["ktm"] { print(" vu 為 \(vu)") } else { print(" dk [\"ktm\"] == nil 為 \( dk ["ktm"] == nil )") } dk["ktm"]=9 dk["honda"]=3 dk["suzuki"]=2 dk["yamaha"]=1 dk["husquana"]=1 //鍵搭配值算ㄧ對,下面範例k 為鍵, v為值 for (k,v) in dk { print( "k 為 \(k) 配的值 為 \(v)") } ``` ``` dk.count 為 0 dk ["ktm"] == nil 為 true dk ["ktm"] = 9 dk.count 為 1 vu 為 9 dk ["ktm"] = 28 dk.count 為 1 vu 為 28 dk ["ktm"] = 28 dk.count 為 0 dk ["ktm"] == nil 為 true k 為 ktm 配的值 為 9 k 為 suzuki 配的值 為 2 k 為 honda 配的值 為 3 k 為 yamaha 配的值 為 1 k 為 husquana 配的值 為 1 ``` ### 建立 「fetch」method 回傳更新數值 ```swift= class Myadt { var son : Int = 1 var mom : Int = 2 func fetch ( ) -> String { var answer : String answer = "\(son)/\(mom)" return answer } } class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() var R0 : Myadt! print("var R0 : Myadt!") // fix 練習 #1 這語法 Myadt ( ) 代表產生一個分數(我們姑且叫做分數 A ) // 應該還要多寫點, 才能解決 fix #0 下面那ㄧ行錯誤的問題 R0 = Myadt() // fix 練習 #0 下行程式執行會不會有問題 R0.son = 17 //分數 A 的分子 設成 17 print("R0.son = 17") // fix 練習 #2 在下行寫點程式, 能分數 A 的分母 設成 23 R0.mom = 23 var msg : String = "1/1" print(" R0 為 ") /* 此實例方法 fetch( ) 產生一個分數A的表示式 "17/23" 被傳回來 */ msg = R0.fetch() print( "\( msg )" ) // 比較ㄧ下: 沒用 object-oriented 物件導向 的理念來開發如下 // 印出一個分數(我們姑且叫做分數 A )的表示式: 分子/分母 // var son0 : Int = 17 // var mom0 : Int = 23 // print("A 為 \( son0 )/\( mom0 )" ) print("var R1 : Myadt!") var R1 : Myadt! R1 = Myadt ( ) /* 這代表一個分數(我們姑且叫做分數 B ) */ R1.son = 29 R1.mom = 19 print( "\( R1.fetch( ) )" ) // “29/19" } } ``` ``` var R0 : Myadt! R0.son = 17 R0 為 17/23 var R1 : Myadt! 29/19 ``` ### 定義類別方法 reference值 ```swift= class B { var married : Bool = false func Ido () { married = true } func Divorce () { married = false } } class ViewController: UIViewController { func kp ( _ _b : B ) { _b.Divorce() } override func viewDidLoad() { super.viewDidLoad() let bb : B = B() bb.Ido() print( bb.married ) kp( bb ) print( "kp( bb )" ) print( bb.married ) } } ``` ``` true kp( bb ) false ``` ### Any 為可存任何資訊的資料型態 ### as! 強型別轉換 ```swift= class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let RG : Int = 83 // fix 練習 #0 觀察下面程式碼 // Any 為可存任何資訊的資料型態, 所以 nta 可存 Int 資料型態的資訊 var nta : Any = RG nta = 83 print(" nta = 83") var 整數K : Int // fix 練習 #1 觀察下行, 執行此程式 // 當您想把 nta 存的 整數查出來, 必須要用 as! 來轉成 Int 資料型態 // , 但為什麼是 轉成 Int 資料型態, 是因您認為 nta 是存 Int 資料型態的資訊 // , 因為 nta 為 Any資料型態, 所以它可存任何資料型態的資訊, 萬ㄧ存的是 false // 這種 Bool 值 // , 所以用 nta as! Int 語法 轉成 Int 會 閃退 整數K = nta as! Int print("整數K + 1 為 \( 整數K + 1 )") print() print() nta = false print(" nta = false") // nta is Int 語法 是去看 nta 存的是不是 Int // 若是, 算出 Bool 型態的值 true, 否則算出 false // fix 練習 #4-1 將下行註解取消 if nta is Int { // fix 練習 #3 將下兩行註解取消, 觀察下行執行時會如何 // 整數K = nta as! Int // print("整數K + 1 為 \( 整數K + 1 )") // fix 練習 #4-2 再將下3行註解取消 } else { print(" nta is Int 為 \( nta is Int )") } print() // fix 練習 #5 執行此程式, 觀察下行 // fix 練習 #2 執行此程式, 觀察下行 print("你能執行到這裡嗎") } } ``` ``` nta = 83 整數K + 1 為 84 nta = false nta is Int 為 false 你能執行到這裡嗎 ``` ### 使用as?推測後轉型,若型別相符得到有值得 Optional,型別不符得到nil ```swift= let RG : Int = 83 // fix 練習 #0 觀察下面程式碼 // Any 為可存任何資訊的資料型態, 所以 nta 可存 Int 資料型態的資訊 var nta : Any = RG nta = 83 print(" nta = 83") print() var pg : Int? // fix 練習 #1 // 當您想把 nta 存的 整數查出來, 必須要用 as? 來轉成 Int? 資料型態 // , 但為什麼是 轉成 Int? 資料型態, 是因為 nta 不一定是存 Int 資料型態的資訊 // , 因為 nta 為 Any資料型態, 所以它可存任何資料型態的資訊, 萬ㄧ存的是 false // 這種 Bool 值 // , 所以這時 轉成 Int? 會是 nil pg = nta as? Int if let uw = pg { print("uw + 1 為 \( uw + 1 )") } else { print("nta as? Int 為 \( nta as? Int )") } print() print() print() nta = false print(" nta = false") print() // fix 練習 #2 // 當您想把 nta 存的 整數查出來, 必須要用 as? 來轉成 Int? 資料型態 // , 但為什麼是 轉成 Int? 資料型態, 是因為 nta 不一定是存 Int 資料型態的資訊 // , 因為 nta 為 Any資料型態, 所以它可存任何資料型態的資訊, 萬ㄧ存的是 false // 這種 Bool 值 // , 所以這時 轉成 Int? 會是 nil pg = nta as? Int if let uw = pg { print("uw + 1 為 \( uw + 1 )") } else { print("nta as? Int 為 \( nta as? Int )") } ``` ``` nta = 83 uw + 1 為 84 nta = false nta as? Int 為 nil ``` ### Optional ```swift= #####swift檔 class B { var _s :String = "ktm" func 傳回字串( ) -> String { // fix 練習 #2 觀察下⾏程式可有執⾏? print("第二步: 有人想要 拿到 _s 資料") return _s } } class A { var _b : B? = nil // 初值設為 nil func 傳回B( ) -> B? { print("第ㄧ步: 有人想要 拿到 _b 資料") print("第ㄧ步: _b == nil 為 \( _b == nil )") print() // fix 練習 #1 觀察下行程式碼 return _b } } ``` ```swift= #####主程式檔 // fix 練習 #0 觀察下面程式碼 let _a : A = A() print("let _a : A = A()") print() // fix 練習 #3-1 // 下⾏ RV 變數的型態為 String? var RV : String? // 注意下⾏的這種 '傳回B( )?' 語法 // 這種語法就是代表盡力執行下去, 能做到哪裡就到哪裡 // 因為最後呼叫的副程式'傳回字串( )' 想傳回字串 // 但若沒有順利地一直執行到這個副程式, 就傳回 nil RV = _a.傳回B( )?.傳回字串( )// fix 練習 #3-2 if let 成功傳回的字串 = RV { print( 成功傳回的字串 ) } else { print( "沒能傳回的字串" ) } ``` ``` let _a : A = A() 第ㄧ步: 有人想要 拿到 _b 資料 第ㄧ步: _b == nil 為 true 沒能傳回的字串 ``` ```swift= // fix 練習 #0 觀察下面程式碼 let _a : A = A() print("let _a : A = A()") let bb : B = B() // fix 練習 #1 觀察下⾏程式 print("_a._b = bb") _a._b = bb print() var RV : String? // fix 練習 #2 // 注意下⾏的這種 '傳回B( )?' 寫法 // 盡力執行下去, 能做到哪裡就到哪裡 RV = _a.傳回B( )?.傳回字串( ) if let 成功傳回的字串 = RV { print( 成功傳回的字串 ) } else { print( "沒能傳回的字串" ) } ``` ``` let _a : A = A() _a._b = bb 第ㄧ步: 有人想要 拿到 _b 資料 第ㄧ步: _b == nil 為 false 第二步: 有人想要 拿到 _s 資料 ktm ``` ### 同名方法 ```swift= class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() print("theTotal 為 \(theTotal)") print("add ( )") // fix 練習 #0 觀察下面三次呼叫 add 方法 add ( ) print("theTotal 為 \(theTotal)") print("add ( 什麼: 9 )") add ( 什麼: 9 ) print("theTotal 為 \(theTotal)") print("add ( howMany: 3 , what: 2 )") add ( howMany: 3 , what: 2 ) print("theTotal 為 \(theTotal)") } var theTotal : Int = 0 func add ( howMany : Int , what : Int ) { if howMany < 1 { return } for _ in 1...howMany { add( 什麼: what ) } } func add ( 什麼 what : Int ) { theTotal += what } func add ( ) { add(什麼: 1) } } ``` ``` theTotal 為 0 add ( ) theTotal 為 1 add ( 什麼: 9 ) theTotal 為 10 add ( howMany: 3 , what: 2 ) theTotal 為 16 ``` ### guard ```swift= func 把您的投資翻倍 ( 投資金額 AssetWr : Int? ) -> Int? { var Answer : Int? = nil // fix 練習 #0 觀察下行 guard let asset = AssetWr else { // , 若 AssetWr == nil // 則執行 else 搭配的 { } 內的程式, 以此範例來說 // , 就是執行 return Answer // 若 AssetWr != nil , 則建立 asset 常數 // 然後繼續從 print("AssetWr != nil") 往下執行 // 注意: 此 asset 常數 可在'往下執行' 的程式碼中可以被使用 guard let asset = AssetWr else { return Answer } print("AssetWr != nil") // fix 練習 #1 觀察下行 // 上面 guard let 建立 的 asset 常數 可被使用 guard asset > 0 else { return Answer } let 兩倍 = Double(asset * 2) let 任意比率 = Double(arc4random()) / Double(UInt32.max) Answer = Int( 兩倍 * 任意比率 ) return Answer } override func viewDidLoad() { super.viewDidLoad() var 募資 : Int? = nil print("募資 = nil") 募資 = nil // fix 練習 #2 觀察下行 '把您的投資翻倍' 被呼叫時的執行結果 if let outcome = 把您的投資翻倍(投資金額: 募資 ) { print( " outcome 是 \(outcome)") } else { print( " 募資 == nil 為 \(募資 == nil)") } 募資 = -200000 print("募資 = -200000") // fix 練習 #3 觀察下行 '把您的投資翻倍' 被呼叫時的執行結果 if let outcome = 把您的投資翻倍(投資金額: 募資 ) { print( " outcome 是 \(outcome)") } else { print( " 募資 == nil 為 \(募資 == nil)") } 募資 = 1000000000 print("募資 = 1000000000") // fix 練習 #4 觀察下行 '把您的投資翻倍' 被呼叫時的執行結果 if let outcome = 把您的投資翻倍(投資金額: 募資 ) { print( " outcome 是 \(outcome)") } else { print( " 募資 == nil 為 \(募資 == nil)") } } } ``` ``` 募資 = nil 募資 == nil 為 true 募資 = -200000 AssetWr != nil 募資 == nil 為 false 募資 = 1000000000 AssetWr != nil outcome 是 1098705392 ``` ### designated initializer(指定初始) & convenience(便利初始) initializer 初始化函式有兩種: Designated Initializer: 類別主要初始化函式。必須讓屬於類別本身所有的屬性完成初始化,然後呼叫父類別的初始化函式繼續完成初始化工作。 Convenience Initialize: 方便使用者設定的初始化函式。使用convenience關鍵字並將某些參數定為預設值,然後呼叫同層的 designaed initializer 或 convenience initializer。 ```swift= #####swift檔##### class Myadt { var 分子 : Int // = 1 var 分母 : Int // = 2 // fix 練習 #0 下行 init 稱呼為 // designated initializer // , 此 initilaizer 會在您用 // Myadt(分子:6,分母:5) 語法產生物件時 // 自動被呼叫, 來達到運用傳進此 initializer // 的兩個參數 來初始 儲存性屬性的值 init(分子 nume :Int,分母 deno :Int) { // 參數 nume 來初始 '分子' 儲存性屬性的值 分子 = nume // 參數 deno 來初始 '分母' 儲存性屬性的值 分母 = deno // designated initializer 要初始 // 所有的 stored properties } // fix 練習 #0 下行 init 稱呼為 // convenience initializer // , 此 initilaizer 會在您用 // Myadt(分子:34) 語法產生物件時 // 自動被呼叫, 來達到初始儲存性屬性的值 convenience init(分子 nume :Int) { // convenience initializer 會在body的開始 // 就呼叫其他的 initializer self.init(分子: nume, 分母: 10) } convenience init ( ) { self.init(分子: 3, 分母: 8 ) } } ``` ```swift= #####viewcontroller##### class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let 分數七 = Myadt(分子:6,分母:5) print( "分數七 為 \(分數七.分子)/\(分數七.分母)") let 分數四 = Myadt(分子:34) print( "分數四 為 \(分數四.分子)/\(分數四.分母)") let 分數八 = Myadt( ) print( "分數八 為 \(分數八.分子)/\(分數八.分母)") } } ``` ``` 分數七 為 6/5 分數四 為 34/10 分數八 為 3/8 ``` ### 帶分數 ```swift= #####swift檔##### // fix 練習 #0 // 帶分數 '是ㄧ種' 分數 // Myadt 是 '帶分數' 的 'super' 類別 // 帶分數 是 'Myadt' 的 '子類別' 或是 // '女兒類別' 註: 在此只是ㄧ種 相互的稱呼 class 帶分數 : Myadt { // fix 練習 #1 var 整數 : Int //因 '帶分數' 的 '整數'部分要由 分子,分母算出來 // 而'super' 類別的 init(分子 nume :Int,分母 deno :Int) // 沒有要由 分子,分母算出來的邏輯, 所以我們要'改寫' override // 這個 init(分子 nume :Int,分母 deno :Int) override init(分子 nume :Int,分母 deno :Int) { 整數 = nume / deno // fix 練習 #2 //要初始所有的 stored properties //才能用 super 呼叫 父類別的 designated initializer. super.init(分子: nume % deno, 分母: deno) } } class Myadt { var 分子 : Int var 分母 : Int init(分子 nume :Int,分母 deno :Int) { 分子 = nume 分母 = deno } convenience init(分子 nume :Int) { self.init(分子: nume, 分母: 10) } convenience init ( ) { self.init(分子: 3, 分母: 8 ) } } ``` ```swift= #####viewcontroller##### class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // fix 練習 #3 測試 '帶分數' 的設計 let 分數n = 帶分數(分子:6,分母:5) print( "\(分數n.整數) 又 \(分數n.分子)/\(分數n.分母)") let 分數f = 帶分數( ) print( "\(分數f.整數) 又 \(分數f.分子)/\(分數f.分母)") } } ``` ``` 1 又 1/5 0 又 3/8 ``` ### 帶分數-1 ```swift= #####swift檔##### class 帶分數 : Myadt { var 整數 : Int // fix 練習 #1 想多設計 有 'intP' 參數的 init init( 整數 intP :Int , 分子 nume :Int,分母 deno :Int) { 整數 = intP super.init(分子: nume , 分母: deno) } // fix 練習 #2 因此必須也改寫 required 的 init required init( 分子 nume :Int,分母 deno :Int) { 整數 = nume / deno super.init(分子: nume % deno, 分母: deno) } } class Myadt { var 分子 : Int var 分母 : Int // fix 練習 #0 'required init' 的設計 required init(分子 nume :Int,分母 deno :Int) { 分子 = nume 分母 = deno } convenience init(分子 nume :Int) { self.init(分子: nume, 分母: 10) } convenience init ( ) { self.init(分子: 3, 分母: 8 ) } } ``` ```swift= #####viewcontroller##### class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // fix 練習 #3 測試 '帶分數' 的設計 let 分數n = 帶分數(整數:1, 分子:1, 分母:5) print( "\(分數n.整數) 又 \(分數n.分子)/\(分數n.分母)") let 分數k = 帶分數( 分子:6,分母:5 ) print( "\(分數k.整數) 又 \(分數k.分子)/\(分數k.分母)") let 分數f = 帶分數( ) print( "\(分數f.整數) 又 \(分數f.分子)/\(分數f.分母)") } } ``` ``` 1 又 1/5 1 又 1/5 0 又 3/8 ``` ### self ```swift= #####swift檔##### class A { var _b : Int = 5 func 加幾個 ( _ 幾個 : Int , _ 什麼 : Int ) { func 加 ( _ 什麼 : Int ) {} for _ in 1...幾個 { // fix 練習 #1 下行運用 self 避免 // 被swift認為您是要取用上面的 '加' // nested function // self 翻譯成 '自己' self.加 ( 什麼 ) } } func 加 ( _ 什麼 : Int ) { var _b : Int = 200 _b += 300 // fix 練習 #0 下行運用 self 避免 // 被swift認為您是要取用上面的 _b // 區域變數 // self 翻譯成 '自己' self._b += 什麼 } } ``` ```swift= #####viewcontroller##### class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let aaa : A = A() print("aaa._b 為 \(aaa._b)") aaa.加幾個 ( 3 , 6 ) print("aaa._b 為 \(aaa._b)") } } ``` ``` aaa._b 為 5 aaa._b 為 23 ``` ### protocol ```swift= protocol The { func 有氣質() func 有貢獻( _ pay : Int ) } class Harry : The { func 有氣質() { print("act like a king") } func 有貢獻( _ pay : Int ) { print("spend \(pay) lb like a wolf licking the blood") } } class William : The { func 有氣質() { print("act like his father") } func 有貢獻( _ pay : Int ) { print("store all the \(pay) lb") } } class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let goodBuy : The = Harry() print("covid18 is spreading") goodBuy.有貢獻(2000000) print("show his grace") goodBuy.有氣質() let likeHisFather : The = William() print("covid18 is spreading") likeHisFather.有貢獻(200000000) print("show his grace") likeHisFather.有氣質() } } ``` ``` covid18 is spreading spend 2000000 lb like a wolf licking the blood show his grace act like a king covid18 is spreading store all the 200000000 lb show his grace act like his father ``` ### protocol_lab ```swift= // fix 練習 #2-1 觀察下面 ViewController 已繼承 UIViewController class ViewController: UIViewController // fix 練習 #2-2 將下行註解取消, 觀察會如何? // 說明: 在此情形下, 要此 ViewController 遵守 The 協定 // 就先寫ㄧ個 , 再寫 The 即可 , The { // fix 練習 #3 將下 6 行註解取消, 觀察會如何? func 有氣質 () { print( "優雅地發表演說" ) } func 有貢獻 ( _ pay :Int ) { print( "把這些錢: \(pay) 元 用來找 免疫學專家 去發明疫苗" ) } var w : The? override func viewDidLoad() { super.viewDidLoad()// fix 練習 #0 執行此程式, 看下面會如何? // fix 練習 #1 將下兩行註解取消, 觀察會如何? print("w = self") w = self // fix 練習 #4 執行此程式, 看下面會如何? print() print( "covid18 is spreading" ) w?.有貢獻 ( 2000000000 ) print("show his grace") w?.有氣質() print() print() } } protocol The { func 有氣質 () func 有貢獻 ( _ pay :Int ) } ``` ``` w = self covid18 is spreading 把這些錢: 2000000000 元 用來找 免疫學專家 去發明疫苗 show his grace 優雅地發表演說 ``` ### data_soure_and_delegate 委派 ```swift= #####swift檔##### // fix 練習 #5 觀察下面的 TheProduct 類別 class TheProduct { var productName : String var unitPrice : Int init( 產品名稱 pn :String, 單價 ur :Int) { productName = pn unitPrice = ur } } ``` ```swift= #####viewcontroller##### class ViewController: UIViewController // fix 練習 #2 將下行註解取消, // 就會消除 fix #1 的語法錯誤 // 但變成這裡有錯誤 , UITableViewDataSource { // fix 練習 #0 執行此程式 // 並觀察 下行的 theTableView 儲存性屬性 // 它存著綠色的 UITableView 物件的參考 // 此 UITableView 上目前並沒有顯示任何產品 @IBOutlet weak var theTableView: UITableView! var theRows : [ TheProduct ]! = [] override func viewDidLoad() { super.viewDidLoad() // fix 練習 #1 將下行註解取消, 觀察下行 // theTableView 的 dataSource 屬性 // 它會設成自己這個 ViewController 的 // 物件的參考 //dataSource 是 UITableViewDataSource? // 型態,而 UITableViewDataSource是ㄧ種協定 //因 ViewController 沒有遵守此協定 // ,所以語法有錯 theTableView.dataSource = self var ep : TheProduct ep = TheProduct(產品名稱: "Arod", 單價: 85) theRows.append(ep) ep = TheProduct(產品名稱: "Bee", 單價: 200) theRows.append(ep) ep = TheProduct(產品名稱: "CheShui", 單價: 105) theRows.append(ep) } // fix 練習 #3 將下四行註解取消, 觀察 // 可有完全消除 fix #2 的語法錯誤 // , 此方法傳回的 Int 資料是代表 // 綠色的 UITableView 要顯示幾筆產品 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return theRows.count } // fix 練習 #4 將下10行註解取消, 觀察 // 總算完全消除 fix #2 的語法錯誤 // , 此方法傳回的 UITableViewCell 是代表 // 綠色的 UITableView 怎麼顯示每筆產品 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "mapd", for: indexPath) let index : Int = indexPath.row cell.textLabel?.text = theRows [ index ].productName cell.detailTextLabel?.text = "\(theRows [ index ].unitPrice)" return cell } } ``` ### closure 閉包 ```swift= class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // fix 練習 #0 觀察下行 theGreaterThan 變數 // 的資料型態為 ( Int , Int )->Bool // 此資料型態稱呼為 closure 翻譯成中文為 '閉包' // '閉包' 資料型態 代表副程式 // 此例 ( Int , Int )->Bool '閉包' 資料型態 // 代表的副程式為 有兩個 Int 型態的參數, 傳回值為 Bool 型態 var theGreaterThan : (Int,Int)->Bool print ("var theGreaterThan : ( Int , Int )->Bool") theGreaterThan = // fix 練習 #1 觀察上行 theGreaterThan 變數要設ㄧ個值, 如下 // 先有ㄧ對大括弧 { } 的左大括弧 { { // 兩個參數的資料型態為 ( Int , Int ) ( Left :Int , Right : Int ) in // 身體 let answer : Bool answer = Left > Right return answer // 傳回傳回值 } // 右大括弧 } var s : Int var t : Int var RR : Bool s = 8 t = 3 print( "s 為 \(s)" ) print( "t 為 \(t)" ) print( "RR = theGreaterThan ( s , t )" ) RR = /* 呼叫 '閉包' */theGreaterThan( s , t ) print( "RR 為 \(RR)" ) print() s = 5 t = 5 print( "s 為 \(s)" ) print( "t 為 \(t)" ) print( "RR = theGreaterThan ( s , t )" ) RR = theGreaterThan( s , t ) print( "RR 為 \(RR)" ) print() s = 9 t = 2 print( "s 為 \(s)" ) print( "t 為 \(t)" ) print( "RR = theGreaterThan ( s , t )" ) RR = theGreaterThan( s , t ) print( "RR 為 \(RR)" ) print() s = 7 t = 8 print( "s 為 \(s)" ) print( "t 為 \(t)" ) print( "RR = theGreaterThan ( s , t )" ) RR = theGreaterThan( s , t ) print( "RR 為 \(RR)" ) } } class Myadt { var 分子 : Int var 分母 : Int init ( 分子 nume : Int , 分母 deno : Int ) { 分子 = nume 分母 = deno } } ``` ``` var theGreaterThan : ( Int , Int )->Bool s 為 8 t 為 3 RR = theGreaterThan ( s , t ) RR 為 true s 為 5 t 為 5 RR = theGreaterThan ( s , t ) RR 為 false s 為 9 t 為 2 RR = theGreaterThan ( s , t ) RR 為 true s 為 7 t 為 8 RR = theGreaterThan ( s , t ) RR 為 false ``` ### closure 閉包_lab ```swift= class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // fix 練習 #0 觀察下行 theCLZ 變數 // 的資料型態為 ( )->Void // 此例 ( )->Void '閉包' 資料型態 // 代表的副程式為 沒有參數, 沒有傳回值 var theCLZ : ( )->Void print ("var theCLZ : ( )->Void") theCLZ = // fix 練習 #1 觀察上行 theCLZ 變數要設ㄧ個值, 如下 // 先有ㄧ對大括弧 { } 的左大括弧 { { // ( ) // 沒有參數 // in // 身體 let RN : UInt32 = arc4random() % 99 + 201 print( "RN 為 \(RN)" ) } // 右大括弧 } var RR : Bool print( "RR = theCLZ ( ) 因為 theCLZ ( ) 沒有傳回值" ) //fix 練習 #3 將下行再變成註解 //fix 練習 #2 將下行註解取消 // 觀察下行的 呼叫 theCLZ '閉包' // , 為什麼有錯 //RR = /* 呼叫 '閉包' */ theCLZ ( ) print() print( "theCLZ ( )" ) //fix 練習 #4 觀察下行的 呼叫 theCLZ '閉包' theCLZ ( ) print( "theCLZ ( )" ) //fix 練習 #5 觀察下行的 呼叫 theCLZ '閉包' theCLZ ( ) } } class Myadt { var 分子 : Int var 分母 : Int init ( 分子 nume : Int , 分母 deno : Int ) { 分子 = nume 分母 = deno } } ``` ``` var theCLZ : ( )->Void RR = theCLZ ( ) 因為 theCLZ ( ) 沒有傳回值 theCLZ ( ) RN 為 281 theCLZ ( ) RN 為 285 ``` ### select _ addTarget ```swift= class ViewController: UIViewController { var theBtn : UIButton! @objc func theIba ( _ sender : UIButton ) { sender.backgroundColor = UIColor.green } override func viewDidLoad() { super.viewDidLoad() theBtn = UIButton() theBtn.backgroundColor = UIColor.darkGray let rct = CGRect(x: 90, y: 90, width: 20, height: 20) theBtn.frame = rct theBtn.addTarget(self,action: #selector( theIba(_:) ), for: .touchUpInside ) view.addSubview(theBtn) } } ``` ### select _ addTarget_lab ```swift= class ViewController: UIViewController { var theBtns : [ UIButton ] = [ ] override func viewDidLoad() { super.viewDidLoad() theBtn = UIButton() theBtn.backgroundColor = UIColor.darkGray theBtn.frame = CGRect(x: 10, y: 90, width: 50, height: 50) theBtn.addTarget( self ,action: #selector( theIba(_:) ), for: .touchUpInside ) view.addSubview(theBtn) theBtns.append( theBtn ) //----------------------------------------------------- theBtn = UIButton() theBtn.backgroundColor = UIColor.purple theBtn.frame = CGRect(x: 10 + 60 , y: 90, width: 50, height: 50) theBtn.addTarget( self ,action: #selector( theIba(_:) ), for: .touchUpInside ) view.addSubview(theBtn) theBtns.append( theBtn ) //----------------------------------------------------- theBtn = UIButton() theBtn.backgroundColor = UIColor.cyan theBtn.frame = CGRect(x: 10 + 120 , y: 90, width: 50, height: 50) theBtn.addTarget( self ,action: #selector( theIba(_:) ), for: .touchUpInside ) view.addSubview(theBtn) theBtns.append( theBtn ) } //----------------------------------------------------- @objc func theIba ( _ sender : UIButton ) { print() for index in 0..<theBtns.count { if theBtns [ index ] === sender { print( "第 \( index ) 個元素" ) break } } print() } var theBtn : UIButton! } ``` ![](https://i.imgur.com/XASRPTW.png) ``` addTarget 第 0 個元素 第 1 個元素 第 2 個元素 ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully