ตัวดำเนินการ“ ++” และ“ -” เลิกใช้ Xcode 7.3 แล้ว


139

ฉันกำลังดูโน้ต Xcode 7.3 และฉันสังเกตเห็นปัญหานี้

ตัวดำเนินการ ++ และ - ถูกเลิกใช้แล้ว

บางคนอธิบายได้ไหมว่าทำไมมันถึงถูกเลิก? และฉันขวาว่าในรุ่นใหม่ของ Xcode ตอนนี้คุณจะใช้แทนการ++นี้x += 1;

ตัวอย่าง:

for var index = 0; index < 3; index += 1 {
    print("index is \(index)")
}

สกรีนช็อตสำหรับเตือน


6
ฉันคิดว่าคำถามนี้ถ้าอยู่นอกขอบเขตของ stackoverflow ส่วนใหญ่เป็นเพราะข้อเสนอที่ยอมรับสำหรับวิวัฒนาการ swift สามารถพบได้ใน Github คุณสามารถอ่านเพิ่มเติมเกี่ยวกับสาเหตุของข้อเสนอนี้github.com/apple/swift-evolution/blob/master / ข้อเสนอ / …
Victor Sigler

7
ฉันกำลังพิจารณาอย่างจริงจังว่าเพิ่งกลับไปที่ Objective-C มันไม่คุ้มค่าที่จะพยายามติดตามการเปลี่ยนแปลงทั้งหมดของ Swift
Greg Brown

3
@OlegGordiichuk มันเป็นสิ่งที่ for-loops เพราะ C-style จะถูกลบออกด้วยดูgithub.com/Vkt0r/swift-evolution/blob/master/proposals/?hl=thดังนั้นคุณจึงไม่จำเป็นต้องใช้ตัวดำเนินการเพิ่มเติม++และ--
Victor Sigler

10
มีการเปลี่ยนแปลงทำลายมากเกินไปสำหรับรสนิยมของฉัน ฉันทั้งหมดเพื่อการปรับปรุง แต่ฉันไม่ต้องการใช้เวลาของฉันเขียนใหม่ส่วนสำคัญของ codebase ของฉันทุกครั้งที่ปล่อยจุด Xcode ออกมา
เกร็กบราวน์

4
@Fogmeister ฉันไม่แน่ใจว่าฉันจะชัดเจนขึ้นได้อย่างไร ฉันต้องการใช้ Swift แต่ไม่รู้สึกว่ามั่นคงเพียงพอ ฉันเคยทำงานกับภาษาอื่นมาอย่างกว้างขวางและไม่เคยพบเจอกับการเปลี่ยนแปลงครั้งใหญ่ในระยะเวลาอันสั้น ฉันรู้สึกเหมือน Apple ต้องการให้เราทุกคนนำ Swift มาใช้ แต่พวกเขาทำให้ยากกว่าที่ควรจะเป็น
Greg Brown

คำตอบ:


210

คำอธิบายเต็มได้ที่นี่จากคริสแลตต์เนอร์ผู้สร้างสวิฟท์ ฉันจะสรุปประเด็น:

  1. เป็นอีกฟังก์ชั่นหนึ่งที่คุณต้องเรียนรู้ขณะเรียนรู้ Swift
  2. ไม่สั้นกว่า x += 1
  3. สวิฟต์ไม่ใช่ซีไม่ควรพกมันไว้เพื่อโปรแกรมเมอร์ซี
  4. การใช้งานหลักคือ C-style สำหรับ loop: for i = 0; i < n; i++ { ... }ซึ่ง Swift มีทางเลือกที่ดีกว่าเช่นfor i in 0..<n { ... }(C-style สำหรับ loop ออกไปเช่นกัน) )
  5. อาจเป็นเรื่องยุ่งยากในการอ่านและบำรุงรักษาเช่นค่าของอะไร x - ++xหรือfoo(++x, x++)?
  6. Chris Lattner ไม่ชอบ

สำหรับผู้ที่สนใจ (และเพื่อหลีกเลี่ยงการเน่าลิงก์) เหตุผลของ Lattner ในคำพูดของเขาคือ:

  1. ตัวดำเนินการเหล่านี้เพิ่มภาระในการเรียนรู้ Swift เป็นภาษาโปรแกรมแรก - หรือกรณีอื่น ๆ ที่คุณไม่รู้จักตัวดำเนินการเหล่านี้จากภาษาอื่น

  2. ข้อได้เปรียบที่แสดงออกของพวกเขานั้นน้อยมาก - x ++ นั้นสั้นกว่า x + = 1 ไม่มาก

  3. Swift เบี่ยงเบนจาก C ไปแล้วโดยที่การดำเนินการ =, + = และการมอบหมายลักษณะอื่น ๆ จะส่งกลับเป็นโมฆะ (ด้วยเหตุผลหลายประการ) ตัวดำเนินการเหล่านี้ไม่สอดคล้องกับรุ่นนั้น

  4. Swift มีคุณสมบัติที่มีประสิทธิภาพซึ่งกำจัดสาเหตุทั่วไปหลายประการที่คุณต้องใช้ ++ i ในรูปแบบ C สำหรับการวนซ้ำในภาษาอื่น ๆ ดังนั้นสิ่งเหล่านี้จึงถูกใช้งานไม่บ่อยนักในรหัส Swift ที่เขียนขึ้นอย่างดี คุณสมบัติเหล่านี้รวมถึงการวนลูปใน, ช่วง, แจกแจง, แผนที่ ฯลฯ

  5. รหัสที่ใช้ค่าผลลัพธ์ของตัวดำเนินการเหล่านี้มักทำให้เกิดความสับสนและบอบบางต่อผู้อ่าน / ผู้ดูแลรหัส พวกเขาสนับสนุนให้รหัส "ยุ่งยากมากเกินไป" ซึ่งอาจจะน่ารัก แต่ยากที่จะเข้าใจ

  6. ในขณะที่ Swift มีลำดับการประเมินที่ดีรหัสใด ๆ ที่ขึ้นอยู่กับมัน (เช่น foo (++ a, a ++)) จะไม่เป็นที่พึงปรารถนาแม้ว่าจะถูกกำหนดไว้อย่างดีก็ตาม

  7. ตัวดำเนินการเหล่านี้สามารถใช้ได้กับประเภทค่อนข้างน้อย: สเกลาร์จำนวนเต็มและทศนิยมและแนวคิดคล้ายตัววนซ้ำ ไม่สามารถใช้กับตัวเลขที่ซับซ้อนการฝึกอบรมและอื่น ๆ

ในที่สุดสิ่งเหล่านี้ทำให้เมตริกของ "ถ้าเราไม่มีสิ่งเหล่านี้เราจะเพิ่มใน Swift 3 หรือไม่"


54
สิ่งที่ฉันคำตอบที่แท้จริงคือหมายเลข 6 นั่นคือตกลงเรา (อดีต C, Java, ... โปรแกรมเมอร์) มีความยืดหยุ่นพอ :-) โดยทั่วไปในโลกแห่งความเป็นจริงการกลายพันธุ์ครอสโอเวอร์และการเลือกก็เพียงพอแล้ว ฉันคุณและคริสเหมือนกันเราทุกคนเป็นผลลัพธ์ของผู้ดำเนินการทั้งสาม ...
user3441734

5
จุดที่ 5: สิ่งเหล่านี้ขึ้นอยู่กับการใช้งานใน C เสมอและไม่มีใครมีความรู้สึกใด ๆ เพียงแค่กำหนดพฤติกรรมและเราจะคุ้นเคยกับมัน ดีกว่าต้องกลับไปเปลี่ยนรหัสเก่าที่ดีอย่างสมบูรณ์แบบโดยไม่มีเหตุผลจริง
ระดับ

3
ฉันชอบประเด็นที่ 3 คุณจะไม่สามารถผูกมัดกับสัญญามรดกได้ตลอดไป ฉันรัก C แต่คุณกำลังสร้างภาษาการเขียนโปรแกรมใหม่ เหมาะสมที่จะเริ่มต้นด้วยกระดานชนวนที่สะอาดเท่าที่คุณต้องการ
Nicolas Miari

8
มันเป็นสาเหตุที่แอปเปิ้ลชอบที่จะบังคับให้คุณคิดเหมือนที่พวกเขาทำ ฉันคิดว่ามันใช้ได้ดีและใช้งานได้ทุกที่ที่คุณต้องการเพื่อเพิ่มหรือลดค่าตัวแปร ไม่ใช่สิ่งที่คุณ "ต้องเรียนรู้" คุณจะทำได้ดีหากไม่มีมัน และ # 5 เป็นโค้ดที่เขียนไม่ดีอย่างที่ฉันไม่เคยเห็น ดังนั้น # 6 มันเป็น การอนุมานมันก็เพียงพอแล้วที่จะทำให้ฉันเกาหัวและค้นหา google ดังนั้นขอบคุณที่เสียเวลากับคริส
csga5000

4
@ csga5000 นั่นเป็นข้อโต้แย้งที่ค่อนข้างอ่อนแอเมื่อพิจารณาว่าคุณสามารถกำหนดโอเปอเรเตอร์ได้เองหากคุณต้องการ มันไม่มีอะไรเกี่ยวข้องกับแอปเปิ้ลที่ต้องการให้คนคิดเหมือนพวกเขา มันไม่เหมาะกับภาษา หาก++ไม่มีอยู่ในภาษา C สไตล์ไม่มีใครในใจที่ถูกต้องของพวกเขาจะมองไปที่การออกแบบของ Swift 3.0 และคิดว่า++ผู้ประกอบการจะเป็นส่วนเสริมที่ดี
overactor

37

ฉันรู้ว่าความคิดเห็นนี้ไม่ได้ตอบคำถาม แต่อาจมีคนที่กำลังมองหาวิธีแก้ปัญหาเพื่อให้ผู้ปฏิบัติงานเหล่านี้ทำงานได้และวิธีการแก้ปัญหาดังกล่าวสามารถพบได้ที่ด้านล่าง😇

โดยส่วนตัวแล้วฉันชอบ++และ--ผู้ประกอบการ ฉันไม่สามารถเห็นด้วยกับความเห็นที่ว่าพวกเขามีเล่ห์เหลี่ยมหรือยากที่จะจัดการ เมื่อนักพัฒนาเข้าใจสิ่งที่ผู้ประกอบการเหล่านี้ทำ (และเรากำลังพูดถึงเรื่องที่ค่อนข้างง่าย) โค้ดควรจะชัดเจนมาก

ในคำอธิบายว่าทำไมผู้ประกอบการถูกคัดค้านกล่าวถึงว่าการใช้งานหลักของพวกเขาในรูปแบบ C สำหรับลูป ฉันไม่รู้เกี่ยวกับคนอื่น แต่โดยส่วนตัวแล้วฉันไม่ได้ใช้ลูปแบบ C เลยและยังมีสถานที่หรือสถานการณ์อื่น ๆ อีกมากมายเมื่อ++หรือ--ผู้ปฏิบัติงานมีประโยชน์

ฉันต้องการพูดถึงว่าvarName++ส่งคืนค่าเพื่อให้สามารถใช้ในreturnขณะที่varName += 1ไม่สามารถ

สำหรับคุณที่ต้องการให้ผู้ให้บริการเหล่านี้ทำงานที่นี่เป็นวิธีแก้ปัญหา:

prefix operator ++ {}
postfix operator ++ {}

prefix operator -- {}
postfix operator -- {}


// Increment
prefix func ++(inout x: Int) -> Int {
    x += 1
    return x
}

postfix func ++(inout x: Int) -> Int {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt) -> UInt {
    x += 1
    return x
}

postfix func ++(inout x: UInt) -> UInt {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int8) -> Int8 {
    x += 1
    return x
}

postfix func ++(inout x: Int8) -> Int8 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt8) -> UInt8 {
    x += 1
    return x
}

postfix func ++(inout x: UInt8) -> UInt8 {
    x += 1
    return (x - 1)
}
prefix func ++(inout x: Int16) -> Int16 {
    x += 1
    return x
}

postfix func ++(inout x: Int16) -> Int16 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt16) -> UInt16 {
    x += 1
    return x
}

postfix func ++(inout x: UInt16) -> UInt16 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int32) -> Int32 {
    x += 1
    return x
}

postfix func ++(inout x: Int32) -> Int32 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt32) -> UInt32 {
    x += 1
    return x
}

postfix func ++(inout x: UInt32) -> UInt32 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int64) -> Int64 {
    x += 1
    return x
}

postfix func ++(inout x: Int64) -> Int64 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt64) -> UInt64 {
    x += 1
    return x
}

postfix func ++(inout x: UInt64) -> UInt64 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Double) -> Double {
    x += 1
    return x
}

postfix func ++(inout x: Double) -> Double {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Float) -> Float {
    x += 1
    return x
}

postfix func ++(inout x: Float) -> Float {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Float80) -> Float80 {
    x += 1
    return x
}

postfix func ++(inout x: Float80) -> Float80 {
    x += 1
    return (x - 1)
}

prefix func ++<T : _Incrementable>(inout i: T) -> T {
    i = i.successor()
    return i
}

postfix func ++<T : _Incrementable>(inout i: T) -> T {
    let y = i
    i = i.successor()
    return y
}

// Decrement
prefix func --(inout x: Int) -> Int {
    x -= 1
    return x
}

postfix func --(inout x: Int) -> Int {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt) -> UInt {
    x -= 1
    return x
}

postfix func --(inout x: UInt) -> UInt {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int8) -> Int8 {
    x -= 1
    return x
}

postfix func --(inout x: Int8) -> Int8 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt8) -> UInt8 {
    x -= 1
    return x
}

postfix func --(inout x: UInt8) -> UInt8 {
    x -= 1
    return (x + 1)
}
prefix func --(inout x: Int16) -> Int16 {
    x -= 1
    return x
}

postfix func --(inout x: Int16) -> Int16 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt16) -> UInt16 {
    x -= 1
    return x
}

postfix func --(inout x: UInt16) -> UInt16 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int32) -> Int32 {
    x -= 1
    return x
}

postfix func --(inout x: Int32) -> Int32 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt32) -> UInt32 {
    x -= 1
    return x
}

postfix func --(inout x: UInt32) -> UInt32 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int64) -> Int64 {
    x -= 1
    return x
}

postfix func --(inout x: Int64) -> Int64 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt64) -> UInt64 {
    x -= 1
    return x
}

postfix func --(inout x: UInt64) -> UInt64 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Double) -> Double {
    x -= 1
    return x
}

postfix func --(inout x: Double) -> Double {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Float) -> Float {
    x -= 1
    return x
}

postfix func --(inout x: Float) -> Float {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Float80) -> Float80 {
    x -= 1
    return x
}

postfix func --(inout x: Float80) -> Float80 {
    x -= 1
    return (x + 1)
}

prefix func --<T : BidirectionalIndexType>(inout i: T) -> T {
    i = i.predecessor()
    return i
}

postfix func --<T : BidirectionalIndexType>(inout i: T) -> T {
    let y = i
    i = i.predecessor()
    return y
}

ฉันไม่ชอบของคุณreturn (x - 1)สำหรับผู้ประกอบการ postfix - IMHO มันสะอาดเพื่อรักษาความหมายที่พวกเขากลับ (สำเนา) มูลค่าเดิมมากกว่าสิ่งที่คุณได้รับถ้าคุณทำx + 1 - 1
Alnitak

ฉันไม่ชอบมัน แต่ฉันไม่รู้เกี่ยวกับวิธีการอื่น ๆ (ดีกว่าสะอาดกว่า) ฉันไม่เข้าใจจุดที่สองของคุณอย่างเต็มที่
0101

1
ฉันเห็นว่าฉันไม่ต้องการทำเช่นนั้นเพียงเพื่อสร้างตัวแปรอื่น ๆ (หรือค่อนข้างคงที่ในกรณีนี้) หากเรากำลังพูดถึงIntเพียงผลของการ(x + 1)จะล้นซึ่งจะขัดจังหวะการดำเนินการและดังนั้นจึงresult - 1จะไม่ได้วิ่ง Doubleตัวอย่างประเภทอื่น ๆนั้นมีลักษณะการทำงานที่แตกต่างกันไปดังนั้นฉันต้องตรวจสอบสิ่งนั้น
0101

3
คุณสามารถใช้deferสิ่งนี้ได้เช่นกัน defer { x += 1 }; return x
Tim Vermeulen

4
ทำไมไม่ใช้ยาชื่อสามัญและเขียนมันในไม่กี่บรรทัด?
μολὼν.λαβέ

22

Apple ได้ทำการลบ ++และทำให้มันง่ายขึ้นด้วยวิธีดั้งเดิมแบบเก่า

แทน +++=คุณจะต้องเขียน

ตัวอย่าง:

var x = 1

//Increment
x += 1 //Means x = x + 1 

ในทำนองเดียวกันสำหรับผู้ประกอบการลดลง--คุณต้องเขียน-=

ตัวอย่าง:

var x = 1

//Decrement
x -= 1 //Means x = x - 1

สำหรับ forลูป:

ตัวอย่างที่เพิ่มขึ้น:

แทน

for var index = 0; index < 3; index ++ {
    print("index is \(index)")
}

คุณสามารถเขียน:

//Example 1
for index in 0..<3 {
    print("index is \(index)")
}

//Example 2
for index in 0..<someArray.count {
    print("index is \(index)")
}

//Example 3
for index in 0...(someArray.count - 1) {
    print("index is \(index)")
}

ตัวอย่างการลดลง:

for var index = 3; index >= 0; --index {
   print(index)
}

คุณสามารถเขียน:

for index in 3.stride(to: 1, by: -1) {
   print(index)
}
//prints 3, 2

for index in 3.stride(through: 1, by: -1) {
   print(index)
}
//prints 3, 2, 1

for index in (0 ..< 3).reverse() {
   print(index)
}

for index in (0 ... 3).reverse() {
   print(index)
}

หวังว่านี่จะช่วยได้!


พวกเขาไม่ได้แทนที่อะไรเลย +=อยู่ที่นั่นตลอด
Nicolas Miari

@ NicolasMiari ใช่เพียงแค่แก้ไขด้วยรูปแบบที่ดีกว่ามาก
Sohil R. Memon

@NicolasMiari คุณช่วยกรุณาตรวจสอบตอนนี้?
Sohil R. Memon

3
สิ่งที่เกี่ยวกับ++iและ--i?
Zigii Wong

7

Chris Lattner ทำสงครามกับ ++ และ - เขาเขียนว่า“ รหัสที่ใช้ค่าผลลัพธ์ของโอเปอเรเตอร์เหล่านี้มักสับสนและละเอียดอ่อนต่อผู้อ่าน / ผู้ดูแลรหัส พวกเขาสนับสนุนให้ใช้รหัส "ที่ยุ่งยากมากเกินไป" ซึ่งอาจจะน่ารัก แต่ยากที่จะเข้าใจ ... ในขณะที่ Swift ได้กำหนดลำดับการประเมินไว้อย่างดีรหัสใด ๆ ที่ขึ้นอยู่กับมัน (เช่น foo (++ a, a ++)) จะไม่เป็นที่พึงปรารถนา มีการกำหนดชัดเจน…สิ่งเหล่านี้ไม่สามารถวัด“ ถ้าเราไม่มีสิ่งเหล่านี้เราจะเพิ่มใน Swift 3 หรือไม่””

แอปเปิ้ลต้องการให้ภาษาสะอาด, ชัดเจน, ไม่สับสนและรวดเร็วตรงไปตรงมา ดังนั้นพวกเขาจึงเลิกใช้ ++ และ - คำหลัก


9
ทำความสะอาด? ดูนรกโทรกลับนี้และเรียกว่าสะอาดหรือไม่ ฉันไม่เห็นด้วย ... และฉันจะเพิ่ม: ปล่อย ++ & - อยู่คนเดียว
mcatach

22
ชอบ...for i in 0.stride(to: 10, by: 2)...หรือ...for i in (1...10).reverse()...สะอาดอะไร!
mad_manny

6
ฉันเห็นด้วย. อาร์กิวเมนต์ 'clean' นั้นขัดแย้งกับพื้นฐานของส่วนที่เหลือของ Swift มาจาก Objective-C ซึ่งไม่สะอาดอย่างเป็นกลางมันค่อนข้างยากที่จะยอมรับ 'สะอาด' เป็นเป้าหมายภาษาของ Apple
Adrian Bartholomew

2
ลองแยก json และรวดเร็วและบอกฉันว่ามันสะอาดแค่ไหน
nickthedude

6

สกรีนช็อตสำหรับเตือน

The Fix-it featureof Xcode ให้คำตอบที่ชัดเจนสำหรับเรื่องนี้

วิธีการเตือน

แทนที่++ increment operatorด้วยแบบเก่าvalue += 1(ตัวดำเนินการมือสั้น) และ-- decrement operatorด้วยvalue -= 1


6

สำหรับ Swift 4 คุณสามารถกู้คืน++และ--ตัวดำเนินการเป็นส่วนขยายIntและประเภทอื่น ๆ นี่คือตัวอย่าง:

extension Int{
   static prefix func ++(x: inout Int) -> Int {
        x += 1
        return x
    }

    static postfix func ++(x: inout  Int) -> Int {
        defer {x += 1}
        return x
    }

    static prefix func --(x: inout Int) -> Int {
        x -= 1
        return x
    }

    static postfix func --(x: inout Int) -> Int {
        defer {x -= 1}
        return x
    }
}

มันทำงานในลักษณะเดียวกันประเภทอื่น ๆ เช่นUIInt, Int8, Float, Doubleฯลฯ

คุณสามารถวางส่วนขยายเหล่านี้ในไฟล์เดียวในไดเรกทอรีรากของคุณและจะสามารถใช้งานได้ภายในไฟล์อื่น ๆ ของคุณที่นั่น

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

เหตุผลที่ฉันโพสต์คำตอบนี้เป็นเพราะฉันไม่เห็นด้วยกับการทำให้ภาษาการเขียนโปรแกรมคอมพิวเตอร์แตกต่างกันโดยไม่จำเป็น

การมีความคล้ายคลึงกันมากระหว่างภาษาทำให้พวกเขาเรียนรู้และสลับจากภาษาหนึ่งไปอีกภาษาหนึ่งได้ง่ายขึ้น

นักพัฒนามักใช้ภาษาการเขียนโปรแกรมหลายภาษามากกว่าหนึ่งภาษา และเป็นเรื่องยุ่งยากที่จะเปลี่ยนจากภาษาหนึ่งเป็นอีกภาษาหนึ่งเมื่อไม่มีการประชุมและไม่มีมาตรฐานทั่วไปในทุกภาษา

ฉันเชื่อว่าควรมีความแตกต่างทางไวยากรณ์ระหว่างภาษาเท่าที่จำเป็นเท่านั้นและไม่มากไปกว่านี้


ฉันรักเมื่อภาษา“ กล้า” แตกต่าง มีภาษา 'C-syntax' ที่ตรงไปตรงมามากเกินไปและ C ได้รับการออกแบบมาเป็นเวลานานแล้ว .. มีประสบการณ์ทางภาษามานานกว่า 50 ปี .. ไม่ว่าคำตอบนี้จะไม่พูดอะไรกับผู้ประกอบการ แต่อย่างใด การโหวต
2864740

5

นี่คือรหัสทั่วไปบางเวอร์ชันที่โพสต์แล้ว ฉันต้องการแสดงความกังวลเช่นเดียวกับคนอื่น ๆ : มันเป็นแนวปฏิบัติที่ดีที่สุดที่จะไม่ใช้สิ่งเหล่านี้ใน Swift ฉันยอมรับว่าอาจทำให้ผู้ที่อ่านรหัสของคุณสับสนในอนาคต

prefix operator ++
prefix operator --
prefix func ++<T: Numeric> (_ val: inout T) -> T {
    val += 1
    return val
}

prefix func --<T: Numeric> (_ val: inout T) -> T {
    val -= 1
    return val
}

postfix operator ++
postfix operator --
postfix func ++<T: Numeric> (_ val: inout T) -> T {
    defer { val += 1 }
    return val
}

postfix func --<T: Numeric> (_ val: inout T) -> T {
    defer { val -= 1 }
    return val
}

ซึ่งสามารถเขียนเป็นส่วนขยายบนชนิดตัวเลขได้


ฉันเพิ่ม@discardableResultแต่ละฟังก์ชั่นเหล่านี้เพื่อปิดเสียงเตือนเกี่ยวกับค่าส่งคืนที่ไม่ได้ใช้ มิฉะนั้นสิ่งที่ฉันกำลังมองหา
Devin Lane

4

จากเอกสาร :

ตัวดำเนินการเพิ่ม / ลดลงใน Swift ถูกเพิ่มเข้ามาเร็วมากในการพัฒนาของ Swift ในฐานะที่เป็นการส่งมอบจาก C สิ่งเหล่านี้ถูกเพิ่มเข้ามาโดยไม่คำนึงถึงมากนักและยังไม่ได้คิดมากนับตั้งแต่นั้นมา เอกสารนี้ให้ภาพลักษณ์ใหม่แก่พวกเขาและในที่สุดเราก็แนะนำให้เราลบมันอย่างสิ้นเชิงเนื่องจากสับสนและไม่ถือน้ำหนัก


ในคำอื่น ๆ การดำเนินการนี้มีราคาแพงเกินไปที่จะใช้?
Oleg Gordiichuk

2
github.com/apple/swift-evolution/blob/master/proposals/ …ที่นี่คุณสามารถอ่านเกี่ยวกับเรื่องนี้ได้ แต่ไม่ใช่เพราะมันมีราคาแพง แต่เป็นการออกแบบภาษา
Dániel Nagy

ดังนั้นในขณะที่ฉัน andersen Swift จะลดการสนับสนุนคุณสมบัติ C-style
Oleg Gordiichuk

2
@OlegGordiichuk ดีฉันจะบอกว่าพวกเขาต้องการที่จะเน้นว่าสวิฟท์ไม่ได้เป็นชุดของ C ซึ่งแตกต่างจาก Objective-C
Dániel Nagy

1
@mah หลายสิ่งที่คุณพูดแค่ไม่สมเหตุสมผลเลย "ไม่ได้มุ่งเน้นไปที่นักพัฒนาที่มีอยู่" ในทางใด ในทำนองเดียวกับที่ Java ไม่ได้มุ่งเน้นไปที่นักพัฒนา PHP? "มุ่งเน้นไปที่สิ่งที่อาจไม่มีความชอบที่จะเป็นนักพัฒนา" หรือไม่? ใช่เพราะผู้ที่ไม่ใช่นักพัฒนามีการกัดมือกับการเขียนโปรแกรมเชิงโปรโตคอลและข้อมูลทั่วไป "วิธีการเปิดใช้งานการออกแบบที่ดี" เพียงแค่ดูที่ SO คุณจะเห็นว่าไม่มีภาษาการเขียนโปรแกรมสามารถ "เปิดใช้งานการออกแบบที่ดี"
Fogmeister

0
var value : Int = 1

func theOldElegantWay() -> Int{
return value++
}

func theNewFashionWay() -> Int{
let temp = value
value += 1
return temp
}

นี่เป็นข้อเสียแน่นอน


5
คุณหมายถึงสง่าใน "คุณต้องจำรายละเอียดปลีกย่อยทั้งหมดของภาษาการเขียนโปรแกรม C มิฉะนั้นจะไม่ชัดเจนทันทีถ้าโทรครั้งแรกกลับ 1 หรือ 2"? ฉันคิดว่าเราทุกคนสามารถสำรองโค้ดพิเศษบางส่วนเพื่อแลกกับการไม่ใช้เวลาหลายนาทีในการเกาหัวของเราพยายามหาสาเหตุข้อผิดพลาดจากความผิดพลาดโง่ ๆ ...
Nicolas Miari

0

เนื่องจากคุณไม่เคยทำงานจริงๆกับคำแนะนำในสวิฟท์ก็เลยทำให้รู้สึกที่จะลบ++และ--ผู้ประกอบการในความคิดของฉัน อย่างไรก็ตามหากคุณขาดไม่ได้คุณสามารถเพิ่มประกาศSwift 5+เหล่านี้ในโครงการของคุณ:

@discardableResult
public prefix func ++<T: Numeric>(i: inout T) -> T {
    i += 1
    return i
}

@discardableResult
public postfix func ++<T: Numeric>(i: inout T) -> T {
    defer { i += 1 }
    return i
}

@discardableResult
public prefix func --<T: Numeric>(i: inout T) -> T {
    i -= 1
    return i
}

@discardableResult
public postfix func --<T: Numeric>(i: inout T) -> T {
    defer { i -= 1 }
    return i
}

-3

ใน Swift 4.1 สามารถทำได้ด้วยวิธีนี้:



    prefix operator ++
    postfix operator ++
    extension Int{
        static prefix func ++(x: inout Int)->Int{
            x += 1
            return x
        }
        static postfix func ++(x: inout Int)->Int{
            x += 1
            return x-1
        }
    }
    //example:
    var t = 5
    var s = t++
    print("\(t) \(s)")


โปรดสังเกตว่าแม้จะมีความจริงที่ว่าโซลูชันนี้คล้ายกับโซลูชันก่อนหน้าในโพสต์นี้พวกเขาไม่ทำงานอีกต่อไปใน Swift 4.1 และตัวอย่างนี้ทำ นอกจากนี้โปรดสังเกตว่าใครก็ตามที่กล่าวถึงข้างต้นว่า + = เป็นการแทนที่สำหรับ ++ เพียงแค่ไม่เข้าใจตัวดำเนินการเช่น ++ ที่รวมกับการกำหนดเป็นสองการดำเนินการจริง ๆ ดังนั้นทางลัด ในตัวอย่างของฉัน:var s = t++ทำสองสิ่ง: กำหนดค่าของ t ให้ s แล้วเพิ่มที ถ้า ++ มาก่อนมันเป็นการดำเนินการสองรายการเดียวกันในลำดับที่กลับรายการ ตามความเห็นของฉันเหตุผลของ Apple เกี่ยวกับสาเหตุที่ต้องลบโอเปอเรเตอร์นี้ (กล่าวถึงในคำตอบก่อนหน้า) ไม่เพียง แต่มีเหตุผลที่ผิดพลาดเท่านั้น แต่ฉันเชื่อว่ามันเป็นเรื่องโกหกและเหตุผลที่แท้จริงคือ มันทำให้พวกเขามีปัญหาในรุ่นก่อนหน้าดังนั้นพวกเขาจึงยอมแพ้ ตรรกะของ "ซับซ้อนเกินกว่าที่จะเข้าใจตัวดำเนินการดังนั้นการลบ" จึงเป็นเรื่องโกหกเพราะ Swift มีตัวดำเนินการที่ซับซ้อนและมีประโยชน์น้อยกว่าซึ่งไม่ได้ลบออก นอกจากนี้ภาษาโปรแกรมส่วนใหญ่ก็มีเช่นกัน JavaScript, C, C #, Java, C ++ และอีกมากมาย โปรแกรมเมอร์ใช้อย่างมีความสุข ใครก็ตามที่ยากเกินไปที่จะเข้าใจตัวดำเนินการนี้

กลยุทธ์ที่อยู่เบื้องหลัง Swift นั้นง่าย: Apple เชื่อว่าโปรแกรมเมอร์นั้นเป็นคนโง่ดังนั้นจึงควรได้รับการปฏิบัติตาม

ความจริงก็คือ Swift ที่เปิดตัวเมื่อเดือนกันยายน 2014 น่าจะเป็นที่อื่นในตอนนี้ ภาษาอื่น ๆ โตเร็วกว่ามาก

ฉันสามารถแสดงรายการข้อผิดพลาดที่สำคัญมากมายในภาษาจากสิ่งที่ร้ายแรง: เช่นอาร์เรย์ที่วางโดยค่าและไม่ใช่โดยการอ้างอิงถึงสิ่งที่น่ารำคาญ: ฟังก์ชั่นพารามิเตอร์ผันแปรไม่สามารถยอมรับอาร์เรย์ที่เป็นแนวคิดทั้งหมดที่อยู่เบื้องหลัง ฉันไม่คิดว่าพนักงานของ Apple จะได้รับอนุญาตให้ดูภาษาอื่นเช่น Java ดังนั้นพวกเขาจึงไม่รู้ด้วยซ้ำว่า Apple นั้นล้าหลังหลายปี Apple อาจใช้ภาษาจาวาเป็นภาษา แต่ทุกวันนี้ความท้าทายไม่ใช่เทคโนโลยี แต่เป็นอัตตา หากพวกเขาจะเปิด IntelliJ เพื่อเขียน Java พวกเขาจะต้องปิดความเข้าใจในธุรกิจของพวกเขาอย่างแน่นอนว่า ณ จุดนี้พวกเขาไม่สามารถและจะไม่ทัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.