ซับสคริปต์และส่วนขยายแบบทั่วไป
ใช้ข้อจำกัดกับซับสคริปต์และส่วนขยาย
ซับสคริปต์และส่วนขยายแบบทั่วไป เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ข้อจำกัดของพารามิเตอร์ชนิด
- อนุประโยค where ในฟังก์ชัน
- การจำกัดชนิดที่เกี่ยวข้อง
- ซับสคริปต์และส่วนขยายแบบทั่วไป