0Pricing
Swift Academy · บทเรียน

ซับสคริปต์และส่วนขยายแบบทั่วไป

ใช้ข้อจำกัดกับซับสคริปต์และส่วนขยาย

ซับสคริปต์และส่วนขยายแบบทั่วไป เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

ซับสคริปต์ generic

ซับสคริปต์สามารถเป็น generic ได้ โดยรับพารามิเตอร์ชนิดข้อมูลของตัวเองที่เป็นอิสระจากชนิดข้อมูลที่ครอบอยู่ จึงทำให้ซับสคริปต์หนึ่งตัวรองรับชนิดข้อมูลขาเข้าได้หลายแบบ

struct Lookup {
    let data = [1, 2, 3, 4, 5]
    subscript<S: Sequence>(indices idx: S) -> [Int] where S.Element == Int {
        idx.map { data[$0] }
    }
}
print(Lookup()[indices: [0, 2, 4]])

เหตุใดจึงใช้ซับสคริปต์ generic

คุณสามารถส่ง Array, Set หรือ Range ของดัชนีไปยังซับสคริปต์เดียวกันได้ เพราะซับสคริปต์นั้นรับ Sequence ของ Int ใด ๆ

struct Lookup {
    let data = [10, 20, 30, 40]
    subscript<S: Sequence>(_ idx: S) -> [Int] where S.Element == Int {
        idx.map { data[$0] }
    }
}
let l = Lookup()
print(l[0...1])
print(l[[3, 0]])

ส่วนขยายที่มีข้อจำกัด

extension ... where จะเพิ่มสมาชิกที่มีอยู่ก็ต่อเมื่อข้อจำกัดเป็นจริง สมาชิกเหล่านี้จะปรากฏบนชนิดข้อมูลเฉพาะเมื่ออาร์กิวเมนต์ generic ตรงตามเงื่อนไข

extension Array where Element: Numeric {
    func sumAll() -> Element { reduce(0, +) }
}
print([1, 2, 3].sumAll())
print([1.5, 2.5].sumAll())

ส่วนขยายสำหรับชนิดขององค์ประกอบเฉพาะ

ใช้ where Element == String เพื่อเพิ่มตัวช่วยเฉพาะสำหรับ String ให้กับอาร์เรย์ของสตริงเท่านั้น

extension Array where Element == String {
    func shout() -> [String] { map { $0.uppercased() + "!" } }
}
print(["hi", "bye"].shout())

ส่วนขยายที่มีข้อจำกัดด้านโปรโตคอล

เพิ่มการทำงานเมื่อองค์ประกอบสอดคล้องกับโปรโตคอลที่กำหนดเอง

protocol Priced { var price: Double { get } }
struct Item: Priced { let price: Double }
extension Collection where Element: Priced {
    var total: Double { reduce(0) { $0 + $1.price } }
}
print([Item(price: 2), Item(price: 3)].total)

ซับสคริปต์ generic ที่คืนค่าชนิดเลือกได้

ซับสคริปต์สามารถเป็น generic และคืนค่าชนิดเลือกได้ เช่น ใช้เข้าถึงดัชนีในคอลเลกชันอย่างปลอดภัย

extension Array {
    subscript(safe i: Int) -> Element? {
        indices.contains(i) ? self[i] : nil
    }
}
print([1, 2, 3][safe: 1] ?? -1)
print([1, 2, 3][safe: 9] ?? -1)

ซับสคริปต์ generic บนพจนานุกรม

ซับสคริปต์ generic สามารถรับลำดับของคีย์และคืนค่า values ที่ตรงกันได้

extension Dictionary {
    subscript<S: Sequence>(keys ks: S) -> [Value] where S.Element == Key {
        ks.compactMap { self[$0] }
    }
}
let d = ["a": 1, "b": 2, "c": 3]
print(d[keys: ["a", "c"]].sorted())

การใช้ร่วมกับ where บน Self

ส่วนขยายของชนิดข้อมูล generic สามารถจำกัดชนิดข้อมูลที่ห่อไว้ เพื่อเปิดเผยส่วนติดต่อการใช้งานที่เหมาะกับชนิดข้อมูลนั้น

struct Stack<T> { var items: [T] = [] }
extension Stack where T: Comparable {
    var peakMax: T? { items.max() }
}
var s = Stack<Int>(); s.items = [3, 9, 1]
print(s.peakMax!)

ซับสคริปต์ generic ที่มีพารามิเตอร์หลายตัว

ซับสคริปต์สามารถรับอาร์กิวเมนต์หลายตัวพร้อมกับพารามิเตอร์ชนิดข้อมูลของตัวเองได้

struct Grid {
    let rows = [[1, 2], [3, 4]]
    subscript(_ r: Int, _ c: Int) -> Int { rows[r][c] }
}
print(Grid()[1, 0])

อ่านอย่างเดียวเทียบกับอ่านและเขียน

เช่นเดียวกับพร็อพเพอร์ตี ซับสคริปต์สามารถมีเพียง get หรือมีทั้ง get และ set เพื่อรองรับการเปลี่ยนแปลงค่า

struct Pad {
    var values = [0, 0, 0]
    subscript(i: Int) -> Int {
        get { values[i] }
        set { values[i] = newValue }
    }
}
var p = Pad(); p[1] = 7
print(p.values)

นำทุกอย่างมาประกอบกัน

ซับสคริปต์ generic และส่วนขยายที่มีข้อจำกัดช่วยให้คุณสร้างส่วนติดต่อการเขียนโปรแกรมที่สื่อความหมาย ปลอดภัยด้านชนิดข้อมูล และปรับใช้ได้กับชนิดขององค์ประกอบหรืออาร์กิวเมนต์ที่นำมาใช้

extension Array where Element: Comparable {
    subscript(topAfterSort i: Int) -> Element { sorted()[i] }
}
print([5, 1, 9, 3][topAfterSort: 0])

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับซับสคริปต์ generic และส่วนขยายที่มีข้อจำกัด

ทบทวน

ซับสคริปต์ generic ประกาศพารามิเตอร์ชนิดข้อมูลและอนุประโยค where ของตนเอง จึงรับชนิดข้อมูลขาเข้าได้หลายแบบ ส่วนขยายที่มีข้อจำกัด (where Element: ... หรือ == ...) จะเพิ่มสมาชิกก็ต่อเมื่อเงื่อนไขเป็นจริง เมื่อนำทั้งสองแนวคิดมาใช้ร่วมกัน จะช่วยสร้างส่วนติดต่อการเขียนโปรแกรมที่ปลอดภัยด้านชนิดข้อมูลและปรับใช้ได้หลากหลาย

คำถามที่พบบ่อย

บทเรียน “ซับสคริปต์และส่วนขยายแบบทั่วไป” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ซับสคริปต์และส่วนขยายแบบทั่วไป” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ซับสคริปต์และส่วนขยายแบบทั่วไป”

ใช้ข้อจำกัดกับซับสคริปต์และส่วนขยาย คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ซับสคริปต์และส่วนขยายแบบทั่วไป” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ข้อจำกัดของพารามิเตอร์ชนิด
  2. อนุประโยค where ในฟังก์ชัน
  3. การจำกัดชนิดที่เกี่ยวข้อง
  4. ซับสคริปต์และส่วนขยายแบบทั่วไป
← กลับไปที่ Swift Academy