องค์ประกอบของไวยากรณ์ที่คุณเกลียดที่สุดในภาษาการเขียนโปรแกรมที่คุณใช้บ่อยคืออะไร? [ปิด]


27

ไม่ว่าคุณจะรักภาษาการเขียนโปรแกรมมากแค่ไหนก็มีรายละเอียดเล็ก ๆ น้อย ๆ อยู่เสมอที่ไม่ดีเท่าที่ควร

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


@Nathan เทย์เลอร์ไม่ได้สำหรับคำถามนี้ แต่สำหรับคำถามอื่น
finnw

คำถามนี้ได้รับการแก้ไขหรือไม่? เพราะเมื่อฉันตอบมันไม่ได้มุ่งเน้นไปที่ "องค์ประกอบไวยากรณ์" ... ฉันจะต้องแก้ไขคำตอบของฉันตอนนี้
Talvi Watia

@Talvi: ไม่มันเกี่ยวกับไวยากรณ์ตั้งแต่เริ่มต้น
Timwi

@ Timwi แปลกมันจะต้องเป็นกรณีของ 'ตอบคำถามที่คิดว่ามันเป็นคนอื่น' แล้ว
Talvi Watia

หากคุณสามารถลงคะแนนและคิดว่านี่เป็นคำถามที่มีประโยชน์หรือมีคำตอบที่เป็นประโยชน์ด้านล่างโปรดลงคะแนน เว็บไซต์ StackExchange ต้องการคะแนนโหวตเพื่อสร้างชุมชนที่ดี คุณสามารถให้ 30 คะแนนต่อวันไม่ต้องเสียพวกเขา ผู้ใช้พิเศษที่มีชื่อเสียงและได้รับคะแนนโหวตต่ำโปรดอ่านสิ่งนี้: meta.programmers.stackexchange.com/questions/393/…
Maniero

คำตอบ:


39

การแทรกเครื่องหมายอัฒภาคใน JavaScript

ฉันไม่ได้ถูกมันกัดบ่อย ๆ แต่มันเป็นความคิดที่ไม่ดีอย่างเหลือเชื่อที่ทำให้หัวฉันหมุน


นี่คือกฎ (จาก ECMA-262 มาตรา 7.9)

  1. เมื่อโปรแกรมมีโทเค็นที่ไม่ได้รับอนุญาตจากไวยากรณ์อย่างเป็นทางการดังนั้นอัฒภาคจะถูกแทรกถ้า (a) มีการแบ่งบรรทัดที่จุดนั้นหรือ (b) โทเค็นที่ไม่คาดคิดเป็นวงเล็บปีกกาปิด
  2. เมื่อถึงจุดสิ้นสุดของไฟล์หากโปรแกรมไม่สามารถแยกวิเคราะห์มิฉะนั้นแล้วอัฒภาคจะถูกแทรก
  3. เมื่อพบ "การผลิตที่ จำกัด " และมีจุดสิ้นสุดบรรทัดในสถานที่ที่ไวยากรณ์มีคำอธิบายประกอบ "[ไม่มี LineTerminator ที่นี่]" จากนั้นแทรกอัฒภาค

ตัวอย่าง:

return 1; // returns 1

return
1; // returns undefined

2
JavaScript: ภาษาโปรแกรมเข้าใจผิดที่ผิดพลาดมากที่สุดในโลก ~ Douglas Crockford
pramodc84

ใช่หลายคนคาดหวังว่าจาวาสคริปต์จะเป็น "ภาษารูปแบบอิสระ" แต่ไม่ใช่
Andreas Rejbrand

13
มันสมเหตุสมผลแล้วเมื่อคุณทราบว่า JavaScript ถูกออกแบบมาเพื่อสร้าง HTML ซึ่งมีประวัติอันยาวนานในการพยายามตีความสิ่งที่รหัสของคุณ "หมายถึง" จริงๆเมื่อมันไม่ถูกต้องทาง syntactically (เงยหน้าขึ้นมองหลักการความทนทานในบางครั้ง - หายนะครั้งใหญ่ที่สุดในประวัติศาสตร์ของการคำนวณ)
Mason Wheeler

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

7
Wohoo ในที่สุดก็มีคนอื่นที่คิดว่า Robustness Principle เป็นภัยพิบัติที่ทำให้ HTML ยุ่งเหยิงไปหมด
Roman Starkov

39

ไวยากรณ์ Java-bean เนื่องจากไม่มีคุณสมบัติ C #

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}

GAH !!!

ปัญหาที่ฉันมีกับสิ่งนี้

  • รหัสมากเกินไป - มีเขตข้อมูลที่ได้รับการบันทึกวิธี getter ที่บันทึกไว้และวิธีการตั้งค่าที่บันทึกไว้ ตัวอย่างพื้นฐานนี้มีรหัส20บรรทัดสำหรับพร็อพเพอร์ตี้เดียว
  • รายการวิธี clutters - "ขอให้ข้าพเจ้าได้วิธีการที่มือเมื่อ: getX, getY, getZ, getAnotherAnnoyingField, getWhyIHateJavaBeans, getThisIsVerbose, getGAH... hashCodeอามีมันเป็น
  • เอกสารหลายพื้นที่นำไปสู่เอกสารที่ไม่ดีล้าสมัยหรือขาดหายไป - น่ารำคาญเมื่อพยายามทำความเข้าใจว่าโค้ดทำอะไร
  • ดังนั้นบุคคลที่สามที่น่ารำคาญจึงต้องมีปลั๊กอินที่จะทำสิ่งนี้ได้อย่างง่ายดาย - Spoon , Sharkและอื่น ๆ

9
อีกครั้งเมื่อโค้ดมีความละเอียดมากว่าต้องการเครื่องมือสร้างอัตโนมัติมีบางอย่างผิดปกติ ฉันเป็นคน NetBeans แต่ก็ยังมีความสามารถในการสร้างผู้ได้รับและตัวตั้งค่าอัตโนมัติ แต่ Javadoc หลุดออกมาจาก syn ก็ยังคง verbose ก็ยังคงเป็นกลุ่ม javadoc ฯลฯ
TheLQ

11
หากคุณต้องการ getters สำหรับทุกสิ่งบางอย่างผิดปกติกับรหัสลูกค้า
finnw

7
มี getters และ setters แบ่ง encapsulation สนามเช่นกันอาจจะpublicเป็น สมาชิกควรเป็นส่วนตัวและควรได้รับการจัดการอย่างสมเหตุสมผลโดยคลาสที่มีตรรกะระดับสูงกว่าไม่ใช่กับ getters และ setters จากรหัสลูกค้า
greyfade

6
@greyfade: หากเป็นสาธารณะคุณจะไม่สามารถเปลี่ยนแปลงสิ่งที่รหัสการตั้งค่าทำได้ง่าย (คุณจะต้องเปลี่ยนรหัสทั้งหมดที่ตั้งค่าเขตข้อมูลจากด้านนอก)
Bart van Heukelom

3
@SHiNKiROU: Java ดูสะอาดหรือไม่ ฉันไม่เคยได้ยินเรื่องนี้มาก่อน! Gripe หลักของฉันกับ Java คือความจริงที่ว่าสิ่งที่ดูเหมือนง่าย ๆ นั้นต้องใช้โค้ดหลายสิบบรรทัดที่ฉันต้องละเว้นทางจิตใจ
ปรับแต่งค่า

33

ความไวของช่องว่าง

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


8
คุณจะได้เรียนรู้ที่จะรักมัน
user10008

2
ไวยากรณ์คืองานนำเสนอ
Winston Ewert

32

switchคำสั่ง (ใน C, C ++, C #, Java, ฯลฯ )

นี่คือตัวอย่างของสาเหตุที่ฉันพบว่ามันไม่สะดวกอย่างมาก:

switch (someVariable)
{
    case 1:
        int i = something();
        doSomething(i);
        break;

    case 2:
        int i = somethingElse();
        doSomethingElse(i);
        break;
}

สิ่งนี้ไม่ได้รวบรวมเพราะตัวแปรiถูกประกาศใหม่ในขอบเขตเดียวกัน ดูเหมือนว่ารายละเอียดเล็ก ๆ น้อย ๆ แต่มันกัดฉันบ่อยมาก ฉันสามารถเพิ่มวงเล็บปีกกาเพื่อบรรเทามันได้ แต่มันคงจะดีถ้าวงเล็บปีกกาเป็นส่วนบังคับของไวยากรณ์และไม่มีการเยื้องซ้ำซ้อนเพิ่มเติม breakฉันยังเกลียดจริงๆต้องเขียนพิเศษ นี่จะดีกว่ามาก:

switch (someVariable)
case 1
{
    int i = something();
    doSomething(i);
}
case 2
{
    int i = somethingElse();
    doSomethingElse(i);
}
default
{
    ...
}

สิ่งนี้ทำให้มันดูเหมือนห่วงโซ่if/ elseซึ่งเป็นสิ่งที่ดีเพราะมันมีความหมายคล้ายกันด้วย อย่างน้อยใน C # มันจะยังคงไม่เหมือนเดิมอย่างไรก็ตามในswitchคำสั่งลำดับของเลเบลเคสไม่สำคัญ แต่ในif/ elseมันทำ


1
น่าเสียดายที่ไวยากรณ์ที่ได้รับการปรับปรุงของคุณมีความสอดคล้องกับฟีเจอร์ที่ใหญ่ที่สุดคือสลับไปมาในภาษาเหล่านี้: Fall-through "อุปกรณ์ของดัฟฟ์" ใน C เป็นตัวอย่างที่สมบูรณ์แบบของคุณค่าของ "คุณลักษณะที่ไม่เหมาะสม" นี้ นอกจากนี้ยังพบได้ทั่วไปในภาษาที่ใช้ภาษา C เช่นเดียวกับการตกหล่นในล่ามและโปรแกรมที่คล้ายกัน
greyfade

7
ไม่มันไม่ได้ทำไปด้วย มันต้องการเพียงแค่ทำให้มันชัดเจนมากขึ้น (ใช้gotoหรือคล้ายกัน) ตามที่เป็นกรณีใน C #
Timwi

8
@greyfade: รหัสใด ๆ ที่ใช้อุปกรณ์ของดัฟฟ์ใน C ต้องตายอย่างน่ากลัว คอมไพเลอร์ตัดสินใจได้ดีขึ้นเกี่ยวกับสิ่งต่าง ๆ เหล่านี้มากกว่าที่คุณทำ
Billy ONeal

4
@greyfade: Delphi case Foo of 1,3: Result := 'odd'; 2,4: Result := 'even' end;รับรอบปัญหาค่าหลายโดยเพียงแค่ช่วยให้ดัชนีในหลายกรณีที่:
Frank Shearar

3
@ jkerian: ตอนนี้ลองจินตนาการว่าbreakเป็นค่าเริ่มต้นและจำเป็นต้องระบุข้อผิดพลาดเท่านั้น ไม่จำเป็นต้องจำเพื่อแสดงความคิดเห็นอีกต่อไป! :)
Timwi

27

การประกาศอาร์เรย์ใน VB.NET

ฉันมักจะลืมว่าเมื่อเริ่มต้นอาร์เรย์คงที่ใน VB.NET คุณกำลังระบุขอบเขตบนของอาร์เรย์และไม่ใช่จำนวนองค์ประกอบเช่นใน C / C ++, PHP หรือ Java นอกจาก VB6 (เราจะไม่ไปที่นั่น ... ) ฉันไม่สามารถนึกถึงภาษาอื่นที่ใช้วิธีนี้:

Dim myArray(20) as Integer  '# Creates an array with 21 elements,
                            '# indexed from 0 to 20

ฉันคิดว่าภาษาเบสิกทุกภาษาทำสิ่งนี้ ... ฉันรู้ว่าทาทาเบอรัสดั้งเดิมและ QBasic ทำ
Michael K

OMG ที่น่ากลัวจริงๆ .... +1
mikera

25

VB6 - การประกาศและการมอบหมายตัวแปรแยกต่างหาก

ภาษาส่วนใหญ่ให้คุณประกาศตัวแปรและกำหนดเป็นรหัสเดียว ในทางกลับกัน VB6 บังคับให้คุณใช้สองอย่าง

Dim i as Integer
i = 0

Dim derpderp as Collection
Set derpderp = new Collection

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

Dim i as Integer: i = 0
Dim derpderp as Collection: Set derpderp = new Collection

7
+1 ที่ต้องใช้ VB6 เป็นภาษาที่ใช้บ่อยที่สุดของคุณ
วอลเตอร์

9
ฉันใช้มันทุกวัน ..
systempuntoout

Pascal ไม่มีไวยากรณ์ที่คล้ายกันหรือไม่ ฉันมักจะคิดว่ามันน่ารังเกียจ
greyfade

1
มีกรณีพิเศษคือถ้าคุณDim Hurp As New Collectionถ้าคุณเข้าถึงHurpเมื่อมันอ้างถึงNothingมันจะถูกเริ่มต้นอย่างน่าอัศจรรย์ก่อนการเข้าถึง หากคุณตั้งไว้อย่างชัดเจนNothingและสัมผัสอีกครั้งมันจะได้รับการฟื้นคืนชีพ ... หอบ!
Jeffrey Hantin

1
+ 1 ล้านสำหรับ Derp Derp de derp de tiddly เล่นเดอร์เดอ
MVCylon

24

แสดงความคิดเห็นใน CSS

//ไม่แสดงความคิดเห็นบรรทัดของรหัสเหมือนที่ทำในภาษาอื่น ๆ เช่น PHP และ Javascript แม้ว่าผลงานที่ผมชอบที่จะใช้/* this is commented out *///

มันน่ารำคาญเพราะครึ่งเวลาที่ฉันลืมฉันแก้ไข CSS แล้วต้องกลับไปแก้ไขข้อผิดพลาด


คุณคิดว่าในวันนี้และอายุที่ CSS ดิบจะถือว่าเป็นรหัสวัตถุ
Tom Hawtin - tackline

// ใช้งานได้ดีเพื่อแสดงความคิดเห็น CSS ฉันทำมันตลอดเวลา สิ่งที่ฉันทำจริงๆคือการพิมพ์ขยะ แต่ดูเหมือนว่าจะทำงานโดยข้ามบรรทัดที่มองไม่เห็น
MVCylon

1
@MVCylon หากคุณใช้ // เพื่อคอมเมนต์บรรทัดสิ่งใด ๆ หลังจากบรรทัดต่อไปนี้ก็จะถูกข้ามไปเช่นกัน {ภายในสไตล์ที่เฉพาะเจาะจง} กล่าวอีกนัยหนึ่งมันล้มเหลวเนื่องจากบรรทัดเหล่านั้นไม่ควรข้าม
Talvi Watia

20

PHP - การเรียงลำดับที่สอดคล้องกันของข้อโต้แย้ง

PHP มีฟังก์ชั่นที่มีประโยชน์มากมายสำหรับการดำเนินการทุกอย่างที่คุณคิดได้ในอาเรย์หรือสตริง การดำเนินการจำนวนมากเหล่านี้ต้องการการใช้ทั้ง a $needleและ a $haystackแต่ฟังก์ชั่นที่แตกต่างกันนำมาใช้ในการสั่งซื้อที่แตกต่าง ฟังก์ชั่นใดที่ต้องใช้การขัดแย้งซึ่งเป็นหนึ่งในข้อเท็จจริงเหล่านั้นที่สมองของฉันปฏิเสธที่จะดูดซับไม่ว่าฉันจะเจอพวกเขาบ่อยแค่ไหน!

รับฟังก์ชั่นin_arrayและstrstr :

// Check whether $needle occurs in array $haystack
bool in_array (mixed $needle, array $haystack [, bool $strict])

// Check whether $needle is a substring of $haystack
string strstr (string $haystack, mixed $needle [, bool $before_needle=false])

น่าสนุกเพียงพอ PHP ดูเหมือนจะสอดคล้องกับลำดับภายในเหล่านี้ซึ่งฟังก์ชั่นสตริงทั้งหมดดูเหมือนจะใช้$haystack, $needleในขณะที่ฟังก์ชั่นอาเรย์เป็นอีกทางหนึ่ง ExpressionEngineมีการโพสต์ที่ดีเกี่ยวกับการเล่นโวหารโดยเฉพาะในรายละเอียดเพิ่มเติมรวมถึงการอภิปรายในรายการ PHP bugsซึ่งมีการตอบสนองสั้น ๆ จากทีม PHP!

helly@php.net
ใช้ IDE ที่เหมาะสมแล้ว

2
มันง่ายต่อการจดจำคำสั่ง$needle, $haystackในขณะที่มันเตือนวิธีการบอกว่าหาเข็มในกองหญ้า
kiamlaluno

3
Protip: ในฟังก์ชั่นอาร์เรย์เข็มจะมาก่อน ในฟังก์ชั่นสตริง, กองหญ้ามาก่อน
GSto

17
strstrฉันรักชื่อ ไร้ความหมายสวยงามมาก
กำหนดค่า

5
เพียงอ่านรายการที่ลิงก์ในตัวแก้ไขข้อผิดพลาดของ PHP อย่างจริงจัง wtf? ความสอดคล้อง oO Imho เป็นปัญหาที่ถูกต้องสำหรับ API ใด ๆ และเพียงแค่ตอบสนองด้วย "ใช้ IDE ที่เหมาะสมจากนั้น" ไม่ใช่คำตอบที่ถูกต้อง อย่างน้อยก็น่าจะได้รับการพูดน้อยโดย devs
Baelnorn

2
จริงๆแล้วสิ่งที่ทำให้ฉันคลั่งไคล้ในเรื่องนี้ก็คือมันไม่ควรเป็นฟังก์ชั่นเลย! มันควรจะเป็นวิธีการ: $ haystack-> find ($ needle) เสร็จสิ้นการจัดการ
riwalk

19

หลาม

self พารามิเตอร์ในข้อกำหนดวิธีการอินสแตนซ์


ในวิธีการเรียนมันมักจะชื่อ cls และการใช้ตัวเองไปกับการประชุม

จริง ๆ แล้วมันสมเหตุสมผลถ้าคุณคิดเกี่ยวกับมัน เหมือนกับการประกาศวิธีส่วนตัวในภาษาอื่น ๆ พารามิเตอร์ของตัวเองนั้นชัดเจนในภาษาไพ ธ อนซึ่งเป็นภาษาอื่นโดยนัย ถ้าคุณต้องการให้มันเป็นนัยให้เพิ่ม @classmethod decorator ก่อนการประกาศเมธอด ดูdocs.python.org/library/functions.html#classmethod การเรียนรู้รายละเอียดเกี่ยวกับวิธีการทำงานนี้จะให้ข้อมูลเชิงลึกเกี่ยวกับวิธีการใช้ภาษาอื่นโดยปริยาย
Evan Plaice

4
ฉันเข้าใจเหตุผลและเหตุผลว่าทำไมมันถึงมีneopythonic.blogspot.com/2008/10//แต่ฉันก็ยังไม่ชอบ
Goran Peroš

@Evan Plaice: 'พารามิเตอร์ของตัวเองชัดเจนในภาษาไพ ธ อนซึ่งเป็นนัยในภาษาอื่น' นั่นเป็นเพียงส่วนหนึ่งของเรื่องราว อีกส่วนหนึ่งคือ python ที่พิมพ์ทุกสัปดาห์ ร่วมกันเป็นเรื่องที่น่ากลัวการลืมselfเกิดขึ้นได้ง่ายและเสียเวลา
maaartinus

@maaartinus จากนั้นเพิ่มมัณฑนากร classmethod ให้กับวิธีการอินสแตนซ์ของคุณ ไม่มีอะไรเกี่ยวข้องกับ 'พิมพ์ที่อ่อนแอ' มันทำให้ความสัมพันธ์ระหว่างวิธีการ / ฟังก์ชั่นแบบคงที่ (ไม่มีพารามิเตอร์ 'ตัวเอง') และวิธีการแบบอินสแตนซ์ (รวมถึง 'ตัวตน') อย่างชัดเจน วิธีการอินสแตนซ์ไม่ทราบว่าเป็นคลาสพาเรนต์จนกว่าคุณจะให้การอ้างอิงแก่มัน ในภาษาอื่น ๆ ลักษณะเด่นที่ฉันระบุไว้นั้นซ่อนอยู่หลังน้ำตาลประโยค ถ้าฉันมีทางเลือกที่จะทำมันทั้งหมดฉันจะเริ่มเรียนรู้ OOP ใน Python ก่อน
Evan Plaice

18

ชวา

ระยะเวลา หยุดเต็ม ตอนจบของเรื่อง.

จะเริ่มที่ไหนดี โอ้ฉันรู้ว่าจะเริ่มต้น: Java ซับซ้อนเมามันและน่าเกลียดและโง่และเสียเนื้อแท้ยาชื่อสามัญ ฉันต้องการพูดอีกหรือไม่ :( ตกลงปรับแล้ว: ลบออกประเภท

จากนั้นมีการจัดการทรัพยากรที่ไม่ได้กำหนดไว้ล่วงหน้า เท้า Kewl!

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

จากนั้นมีข้อบกพร่องที่ทางลัดคลาสอักขระไม่ทำงานบนไม่ใช่ ASCII ช่างเป็นความเจ็บปวด! และไม่ได้พิจารณาการใช้\p{javaWhiteSpace}; มันไม่ได้ทำสิ่งที่ถูกต้องกับจุดรหัสช่องว่าง Unicode ที่พบบ่อยมาก

คุณรู้หรือไม่ว่ามี\p{javaJavaIdentifierStart}ทรัพย์สิน? พวกเขากำลังคิดอะไรอยู่? ดีใจที่พวกเขามีนักสำรวจสมาร์ทเช่น wurkin ในเรื่องที่ยาก

เคยลองใช้ธง CANON_EQ ไหม คุณรู้หรือไม่ว่าทำจริงและไม่ทำอะไร? แล้วเรื่องที่เรียกว่า“ Unicode case”? สิ่งต่าง ๆ ที่ห่อหุ้มตามปกติไม่ได้ผล

จากนั้นพวกเขาทำให้การเขียน regexes ที่บำรุงรักษาทำได้ยาก Java ยังไม่เข้าใจวิธีการเขียนสตริงหลายบรรทัดดังนั้นคุณจะต้องเขียนสิ่งที่ไม่ดีเช่นนี้:

    "(?= ^ [A-Z] [A-Za-z0-9\\-] + $)      \n"
  + "(?! ^ .*                             \n"
  + "    (?: ^     \\d+      $            \n"
  + "      | ^ [A-Z] - [A-Z] $            \n"
  + "      | Invitrogen                   \n"
  + "      | Clontech                     \n"
  + "      | L-L-X-X                      \n"
  + "      | Sarstedt                     \n"
  + "      | Roche                        \n"
  + "      | Beckman                      \n"
  + "      | Bayer                        \n"
  + "    )      # end alternatives        \n"
  + ")          # end negated lookahead   \n" 

บรรทัดใหม่เหล่านั้นคืออะไร โอ้เพียงแค่ความโง่เขลาของ Java พวกเขาใช้ความคิดเห็น Perl ไม่ใช่ความคิดเห็น Java ( iDiots! ) ซึ่งไปจนถึงจุดสิ้นสุดของบรรทัด ดังนั้นหากคุณไม่ใส่สิ่งเหล่านั้นไว้\nคุณจะตัดส่วนที่เหลือของแบบแผนของคุณออก Duh และ double duh!

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

จากนั้นเราสามารถเริ่มพูดถึงเรื่องไร้สาระของ Java ด้วยการเข้ารหัส สิ่งแรกคือความจริงที่ว่าการเข้ารหัสแพลตฟอร์มเริ่มต้นนั้นเป็นการเข้ารหัสแบบ 8 บิตที่อ่อนแอเสมอแม้ว่า charchars ของ Java จะเป็น Unicode ก็ตาม จากนั้นมีวิธีที่พวกเขาไม่ยกข้อยกเว้นเกี่ยวกับข้อผิดพลาดในการเข้ารหัส คุณรับประกันว่าจะได้รับอึ หรือวิธีการเกี่ยวกับเรื่องนี้:

OutputStreamWriter(OutputStream out) 
          Creates an OutputStreamWriter that uses the default character encoding.
OutputStreamWriter(OutputStream out, Charset cs) 
          Creates an OutputStreamWriter that uses the given charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 
          Creates an OutputStreamWriter that uses the given charset encoder.
OutputStreamWriter(OutputStream out, String charsetName) 
          Creates an OutputStreamWriter that uses the named charset.

ความแตกต่างคืออะไร? คุณรู้หรือไม่ว่ามีเพียงหนึ่งข้อเท่านั้นที่จะเพิ่มข้อยกเว้นหากคุณมีข้อผิดพลาดในการเข้ารหัส ที่เหลือก็แค่ปากกระบอกปืนพวกมัน

จากนั้นก็มีความโง่ของตัวอักษร Java ที่ไม่เพียงพอที่จะถือตัวละคร! พวกเขากำลังคิดอะไรอยู่? นั่นเป็นเหตุผลที่ฉันเรียกพวกเขาว่า charchars คุณต้องเขียนโค้ดแบบนี้หากคุณคาดหวังว่ามันจะทำงานได้ถูกต้อง:

private static void say_physical(String s) { 
    System.out.print("U+");
    for (int i = 0; i < s.length(); i++) {
        System.out.printf("%X", s.codePointAt(i));
        if (s.codePointAt(i) > Character.MAX_VALUE) { i++; }  // UG!
        if (i+1 < s.length()) { System.out.printf("."); }
    }
}

และใครที่เคยคิดที่จะทำเช่นนั้น? ถัดจากไม่มีใครเลย

มีอักขระกี่ตัว"\uD83D\uDCA9"? หนึ่งหรือสอง? ขึ้นอยู่กับว่าคุณจะนับมันอย่างไร หลักสูตรของ regex เกี่ยวข้องกับตัวอักษรแบบโลจิคัลดังนั้นรูปแบบ^.$จะประสบความสำเร็จและรูปแบบ^..$จะล้มเหลว ความบ้านี้แสดงให้เห็นที่นี่:

String { U+61, "\u0061", "a" }  =~ /^.$/ => matched.
String { U+61, "\u0061", "a" }  =~ /^..$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^.$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^..$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^.$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^..$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^.$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^..$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^.$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^..$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^.$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^..$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "💩" }  =~ /^.$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "💩" }  =~ /^..$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "💩💩" }  =~ /^.$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "💩💩" }  =~ /^..$/ => matched.

ความโง่เง่านั้นเป็นเพราะคุณไม่สามารถเขียนสิ่งที่สมเหตุสมผลอย่างสมบูรณ์\u1F4A9และแน่นอนคุณไม่ได้รับคำเตือนใด ๆ ที่คุณไม่สามารถทำได้ มันแค่ทำสิ่งผิด

Stoooopid

ในขณะที่เราอยู่ที่มัน\uXXXXสัญกรณ์ทั้งหมดเป็นสมองพิการ แต่กำเนิด ตัวประมวลผลล่วงหน้า Java ( ใช่คุณได้ยินฉัน ) มาถึงก่อนที่ Java จะทำดังนั้นคุณจึงไม่ได้รับอนุญาตให้เขียนสิ่งที่สมเหตุสมผลอย่างสมบูรณ์เช่น"\u0022"เนื่องจากเมื่อ Java เห็นว่าตัวประมวลผลล่วงหน้าได้กลายเป็น"""ดังนั้นคุณจะสูญเสีย เดี๋ยวก่อนไม่ใช่ว่าอยู่ใน regex! ดังนั้นคุณสามารถใช้งานได้"\\u0022"ดี

Riiiiiiiight!

คุณรู้หรือไม่ว่า Java ไม่สามารถisatty(0)โทรออกได้ คุณไม่ได้รับอนุญาตให้คิดความคิดเช่นนั้น มันจะไม่ดีสำหรับคุณ

และจากนั้นก็มีสิ่งที่น่ารังเกียจ classpath ทั้งหมด

หรือความจริงที่ว่าไม่มีวิธีที่จะระบุการเข้ารหัสของไฟล์ต้นฉบับ Java ของคุณในไฟล์ต้นฉบับเดียวกันดังนั้นคุณจะไม่สูญเสียมัน ฉันต้องการทราบอีกครั้งว่าอะไรที่พวกเขาคิดว่าดี

หยุดความบ้าคลั่ง! ฉันไม่อยากเชื่อเลยว่าผู้คนจะทนกับขยะนี้ได้ มันเป็นเรื่องตลกที่สมบูรณ์ ฉันอยากจะเป็นวอล - มาร์ทมากกว่าที่จะต้องทนทุกข์ทรมานกับการถูกเชือดและลูกธนูของความบ้าคลั่งของชวา ทุกอย่างพังทลายและพวกเขาไม่สามารถแก้ไขได้ แต่ไม่สามารถแก้ไขได้

สิ่งนี้เกิดขึ้นได้จากคนที่ชอบสุนัขจิ้งจอกคนเดียวที่มีความภาคภูมิใจในภาษาที่ทำให้มันผิดกฎหมายที่จะมีprintf()ฟังก์ชั่น Gee นั้นได้ผลจริงดีใช่มั้ย!

เชียร์ numbskulls Bitch-slapping นั้นใจดีเกินไปสำหรับพวกเขา ถ้าฉันต้องการที่จะเขียนโปรแกรมในการประกอบฉันจะ นี่ไม่ใช่ภาษาที่ใช้กู้ได้ จักรพรรดิไม่มีเสื้อผ้า

เราเกลียดมัน เราเกลียดมันตลอดไป ปล่อยให้มันตายตายตาย !


ฮ่าฮ่า, ดีมาก, ฉันไม่ได้สัมผัสจาวาเพราะมันไม่ได้เงาเหมือนที่คุณอธิบาย สำหรับ \ uD83D ... ดีฉันคิดว่าวิธีที่ดีกว่าในการพูดแบบนี้ก็คือคุณควรจะใช้สตริงไม่ใช่ UTF-16 แต่เป็น UTF-32 แทน หากคุณยอมรับ UTF-16-ness แล้ว regex จะทำสิ่งที่ถูกต้อง มันคือการเรียกความยาว
Roman Starkov

4
-1 ด้วยข้อยกเว้นของความคิดเห็น regexp และ Unicode escapes ไม่ใช่สิ่งเดียวที่คุณกล่าวถึงเป็นองค์ประกอบไวยากรณ์
Jörg W Mittag

3
@ Jörgคุณต้องการไวยากรณ์หรือไม่ ตกลง: Java อนุญาตให้คุณใส่อักขระควบคุมรวมถึง ESC และ NUL ในตัวระบุ พวกเขากำลังคิด WTH ???
tchrist

4
@tchrist: ว้าว! ถ้าฉันเคยเขียนโปรแกรม Java อีกครั้งตัวแปรทั้งหมดของฉันจะมีชื่อที่ประกอบด้วยตัวเลขของอักขระ backspace ที่แตกต่างกัน ( ^H) :)
j_random_hacker

1
@ คริสร์ตอนนี้รู้สึกดีขึ้นไหม?

16

ฟังก์ชั่นการประกาศตัวชี้ไวยากรณ์ใน C และ C ++:

(int)(*f)(int, int);

ที่ประกาศตัวชี้ฟังก์ชั่นที่มีชื่อว่าfมี pointee สามารถใช้เวลาสองและกลับintint

ฉันชอบไวยากรณ์แบบนี้มาก:

f: (int, int) => int

สมมติว่าคุณต้องการที่จะประกาศตัวชี้ฟังก์ชันgที่มี pointee สามารถใช้เวลาสองintและฟังก์ชั่นจากintและintไปและกลับintint

ด้วยเครื่องหมาย C หรือ C ++ คุณจะประกาศเป็น:

(int)(*g)(int, int, int(int, int));

ด้วยสัญกรณ์ที่เสนอข้างต้นสิ่งเดียวกันสามารถประกาศเป็น:

g: (int, int, (int, int) => int) => int

ยุคสุดท้ายนั้นเป็น IMO ที่ใช้งานง่ายกว่า


นอกเหนือ: ภาษาการเขียนโปรแกรมที่เรียกว่า OOC แก้ไขไวยากรณ์นี้ (และปัญหาการสร้างประโยคอื่น ๆ ใน C และ C ++) ตรวจสอบที่หน้าแรกของที่นี่


เห็นด้วยบางอย่าง "ธรรมดา C" / "C ++" ไม่รองรับหรือสนับสนุนด้วยไวยากรณ์ที่แตกต่างกัน ไวยากรณ์พิเศษช่วยระบุเมื่อสนับสนุนคุณสมบัติการเขียนโปรแกรมภาษา นั่นคือเหตุผลที่เพิ่ม C # "ผู้รับมอบสิทธิ์" ไวยากรณ์
umlcat

ผู้ได้รับมอบหมายไม่เพียง แต่เป็นน้ำตาล syntactic เพราะพวกเขายังเก็บวัตถุ (ตรงกันข้ามกับตัวชี้ฟังก์ชั่นสมาชิก C ++ ที่มีไวยากรณ์แย่ยิ่งกว่าตัวชี้ฟังก์ชั่นปกติ)
Tamás Szelei

14

คำฟุ่มเฟื่อยใน Java

เช่น:

public static final int 

6
เปรียบเทียบกับ? (15 ตัวอักษร)
TheLQ

7
เปรียบเทียบกับ: const intเช่น
OscarRyz

11
"สาธารณะคงสุดท้ายสุดท้าย int x = 4;" เปรียบเทียบกับ "x = 4" ใน Haskell
Jared Updike

24
นั่นไม่ใช่คำฟุ่มเฟื่อย ลองเขียนa+(b*c)/d*e+f/g^20โดยใช้BigIntegerใน Java เหตุใดภาษานี้จึงไม่อนุญาตให้ผู้ให้บริการโหลดมากเกินไป
MAK

4
@Michael: โปรแกรมเมอร์ที่ต้องได้รับการปกป้องด้วยตนเองในราคานี้สามารถป้องกันตัวเองได้ดีที่สุด (และลดความเจ็บปวดสำหรับคนอื่น) โดยไม่ต้องเขียนโปรแกรมเลย: D
MAK

12

\ we \ wouldnt \ fix \ ไวยากรณ์ namespace ของเรา parser ใน PHP

ไวยากรณ์ไม่เพียง แต่น่าเกลียด แต่ยังนำไปสู่ความสับสนเมื่อนักพัฒนารุ่นใหม่ต้องคิดถึงเนมสเปซในสตริง (PHP สอดแทรกแบ็กสแลชในสตริง double-quote เป็น escape sequences การพยายามแสดงเนมสเปซเช่น\you\should\never\do\thatในสตริง double-quote แทนที่จะเป็นสตริงที่มีเครื่องหมายอัญประกาศเดี่ยวจะนำไปสู่การขึ้นบรรทัดใหม่แท็บและภัยพิบัติ)


ใช่มีคนคิดว่า :: วิธีที่ดีกว่าในการทำเช่นนี้ แต่ PHP ยืนยันว่าผู้ประกอบการทุกคนต้องแตกต่าง ฉันอยากรู้ว่าปัญหาการใช้ผิดประเภทอยู่ที่นี่อย่างไร
Alan Pearce

ตกลง. PHP ต้องการเนมสเปซ, แต่ไวยากรณ์นั้นทำให้มันผิดพลาดขึ้นมา
umlcat

9

ฉันดูถูกความจริงที่ว่าเครื่องมือจัดฟันแบบหยิกสามารถเลือกได้หลังจากคำสั่ง if / while /

โดยเฉพาะอย่างยิ่งเมื่อฉันเห็นรหัสเช่น

if (...)
    for(...)
        ... One line of stuff ...

กรุณาใส่เครื่องมือจัดฟันและทำด้วยมัน


6
อืม .. สิ่งนี้ขึ้นอยู่กับ สำหรับ "Abort Ifs" ซึ่งเพียงตรวจสอบเงื่อนไขและส่งคืนรหัสข้อผิดพลาด (หรือโยนข้อยกเว้น) ฉันจะค่อนข้างไม่เห็นเครื่องมือจัดฟัน
Billy ONeal

4
ฉันจะเห็นด้วยถ้าคุณ จำกัด ตัวเองไว้เฉพาะกรณีที่มีหลายระดับมาก แต่คำพูดของคุณนั้นแคบเกินไป มียูทิลิตี้ที่ยอดเยี่ยมในความสามารถในการมีรูปแบบสั้น ๆ สำหรับคำสั่ง ifs และลูปแบบง่าย ๆ
Timwi

2
กฎของฉัน: เฉพาะในกรณีที่คำสั่งต้องการหลายสถานะย่อยหรือถ้ามันมีคำสั่งดังกล่าวควรห่อด้วยเครื่องหมายวงเล็บ ดังนั้นจึงfor (...) while (...) if (...) { x(); y(); }เป็นการเขียนที่ดีกว่าfor (...) { while (...) { if (...) { x(); y(); } } }โดยมีการย่อหน้าที่เหมาะสม
Jon Purdy

6
ฉันค่อนข้างตรงกันข้าม - ฉันดูถูกคนที่ยืนยันในการจัดฟันเมื่อพวกเขาไม่จำเป็นโดยสิ้นเชิง เพียงเรียนรู้การเขียนโปรแกรม
Jerry Coffin

3
ฉันชอบวงเล็บแม้จะเป็นประโยคเดียว มันทำให้ฉันติดตามโฟลว์ของโปรแกรมได้ดีขึ้น
Ricardo Santos

9

VBScript ไม่มีตัวดำเนินการเชิงตรรกะ

ต่างจากภาษาที่เข้าใจได้เกือบทุกภาษา VBScript ใช้ตัวดำเนินการระดับบิตแทนตัวดำเนินการทางตรรกะ ในทางปฏิบัติหมายความว่าอย่างไร อย่างที่Eric Lippert ชี้ให้เห็น :

If Blah = True Then Print "True!" Else Print "False!"

และ

If Blah Then Print "True!" Else Print "False!"

ไม่เหมือนกันใน VBScript!

แม้ว่าจะแย่กว่านั้นซึ่งหมายความว่าไม่มีการประเมินการลัดวงจรใน VBScript ดังนั้นคำสั่งต่อไปนี้จะขัดข้องโปรแกรมของคุณถ้าBlahเป็นNothing

If (Not Blah Is Nothing) And (Blah.Frob = 123) Then
...

ถูกต้องแล้ว VBScript จะประเมินทั้งสองส่วนของการเปรียบเทียบและแม้ว่าส่วนแรกจะเป็นเท็จ! เพียงแค่ปล่อยให้จมลงใน ...


3
จนถึงวันที่คุณตามล่าหาบั๊กภายในIf x Then ... If Not x Then ... End If ... End Ifและหาว่า x คือ 2 คุณยังไม่ได้โปรแกรมใน VB / VBScript จริงๆ
ปรับแต่งค่า

7

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

ฉันเกลียดวิธีที่ตัวชี้ฟังก์ชั่นดูใน C. โดยปกติการประกาศตัวแปรใด ๆ ดูเหมือนเป็น tuple ของ: type varname; การประกาศตัวชี้ฟังก์ชั่นในทางกลับกันดูเหมือนการประกาศฟังก์ชันด้วย * หน้าชื่อฟังก์ชัน ฉันสามารถยอมรับสิ่งนี้เป็นคำอธิบายของตัวชี้ประเภท แต่ใน C นี้ประกาศทั้งประเภทและชื่อของตัวแปรประเภทนั้น สิ่งนี้ดูไม่สอดคล้องกับฉันเพราะการประกาศประเภทแตกต่างจากการประกาศตัวแปรอย่างอื่น เพียงกำหนดประเภทก็ไม่ได้กำหนดชื่อตัวแปรstruct myStruct{int X; int Y;} myStructในทำนองเดียวกันฉันไม่เห็นเหตุผลสำหรับการประกาศประเภทและการประกาศตัวแปรที่จะจัดกลุ่มเป็นคำสั่งอะตอมเดียวในตัวชี้ฟังก์ชั่นและฉันไม่ชื่นชมความเบี่ยงเบนจากtype varname;โครงสร้าง

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


1
มันสอดคล้องกับส่วนที่เหลือของภาษาดังนั้นมือจับของคุณอาจจะเกี่ยวกับไวยากรณ์ของ C declarators โดยทั่วไป? คุณชอบไวยากรณ์ที่ใช้ในGoหรือไม่?
finnw

สอดคล้องในทางใด? โดยปกติแล้วมันจะไป: พิมพ์ varname; และเมื่อเราสร้างคอมโพสิตชนิดใหม่เช่น struct ก่อนอื่นมาประกาศอาจมี typedef แล้วเราสร้างตัวแปรประเภทนั้น เมื่อเราประกาศตัวชี้ฟังก์ชั่นมันเป็น int (* foo) (int arg1, int arg2) ซึ่งจะใช้เป็นประเภทของอาร์กิวเมนต์ที่ส่งผ่านไปยังฟังก์ชัน: void newFoo (int (* foo) (int arg1, int art2 )) .... และเป็นตัวแปร: foo = a_compatible_func; ฉันคิดว่าการประกาศฟังก์ชั่นก่อนแล้วประกาศ var ต่อไปจะสอดคล้องกันเช่น: typedef int (* foo) (int, int) MyFoo; MyFoo myfoo;
EpsilonVector

typedefนั่นเป็นเหตุผลที่คุณมี
zneak

4
@EpsilonVector: ฉันมีแนวโน้มที่จะยอมรับว่าไวยากรณ์ตัวชี้ฟังก์ชั่นน่ารังเกียจ แต่มีกฎง่ายๆที่จะปฏิบัติตามที่ทำให้อ่านง่ายขึ้น กฎตามเข็มนาฬิกาเกลียว (บางทีคุณอาจเคยเห็นมัน?): c-faq.com/decl/spiral.anderson.html
greyfade

1
EpsilonVector: ฉันไม่แน่ใจว่าสิ่งที่คุณคาดหวังจากการประกาศตัวแปรตัวชี้เพื่อประกาศอื่นที่ไม่ใช่ชื่อของตัวแปร

6

อัฒภาคใน VBScript - หรือขาด

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


4
การลงคะแนนเสียงแบบนี้ไม่ใช่เพราะฉันชอบอัฒภาค แต่โดยเฉพาะเพราะฉันเกลียดวิธีที่ VB กระตุ้นให้สายยาวมาก ๆ
Shog9

6

อาร์กิวเมนต์เข้า / ออก ฉันทุกคนมีข้อโต้แย้ง (เป็นสิ่งที่ดีฉัน) การโต้แย้งออกมาก็ดีเช่นกัน แต่การโต้เถียงที่ต้องสื่อให้ทั้งสองรัฐทำให้ฉันโกรธ

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


คุณมีภาษาอะไรในใจ? ถ้า C # ฉันจะไม่เห็นด้วยว่ามันน่ารำคาญเพราะมันชัดเจนอยู่เสมอ (ต่างจาก C ++) และฉันก็ไม่รู้ภาษากระแสหลักใด ๆ ที่คุณถูกบังคับให้ประกาศข้อโต้แย้งเหมือนเข้า / ออก
finnw

@finnw ฉันไม่เคยเห็นภาษาที่คุณต้องพูดinเพื่อinโต้แย้งด้วยฉันแค่พูดถึงพวกเขา นอกจากนี้ในความคิดของฉันไม่มีอะไรสามารถแก้ตัวข้อโต้แย้งเข้า / ออกและทำให้พวกเขาชัดเจนไม่บรรเทาความเจ็บปวด ไม่ควรมีเหตุผลที่จะต้องเริ่มต้นตัวแปรท้องถิ่นด้วยค่าที่เป็นประโยชน์ต่อฟังก์ชั่นและมีตัวแปรเดียวกันนี้ทันทีจากนั้นมีสิ่งที่ฟังก์ชั่นตัดสินใจที่จะใส่ สองคนนี้ควรชัดเจน เสมอ.
zneak

ขอโทษฉันไม่ชัดเจนมาก ฉันหมายถึงการพูดว่า "ฉันไม่รู้ภาษาใด ๆ ที่ข้อโต้แย้งทั้งหมดอยู่ใน + out" คือคุณไม่ได้ถูกบังคับให้ใช้คุณลักษณะนั้น แต่มีกรณีการใช้ที่ถูกต้อง (เช่นการอัปเดตstructค่าที่ขึ้นอยู่กับค่าใหม่ ของฟิลด์อื่นในฟิลด์เดียวกันstruct)
finnw

@finnw วัตถุที่ส่งผ่านโดยการอ้างอิง (เช่นอินสแตนซ์ของclassวัตถุใน C #) การแก้ไขโดยฟังก์ชั่นจะดีสำหรับฉัน นอกเหนือที่ผมไม่ชอบ structs ที่ไม่คงที่ผ่านstructกับrefคำหลักที่จะปรับปรุงมันจะถูกเกินไป สิ่งที่ฉันเกลียดคือเมื่ออินพุตถูกเขียนทับด้วยเอาต์พุต ตัวอย่างที่ดีที่สุดที่ฉันนึกได้ก็คือacceptฟังก์ชั่นซ็อกเก็ตของ Berkeley : มันต้องมีการsocklen_t*โต้แย้งว่าในการป้อนข้อมูลจะต้องมีขนาดของstruct sockaddr*คุณได้ผ่าน; และในเอาต์พุตจะมีจำนวนไบต์ที่เขียนลงไป สิ่งนี้ควรเป็นความผิดทางอาญา
zneak

ฉันยอมรับว่าไม่ดี (IIRC บางฟังก์ชั่น Win32 I / O ทำเหมือนกัน) แต่นั่นเป็นการใช้งานในทางที่ผิด (ฟังก์ชั่นการโทรเปลี่ยนความหมายของตัวแปรที่ส่งผ่านไม่ใช่แค่ค่าของมัน) และไม่ได้หมายถึงคุณสมบัติ ตัวเองไม่ดี
finnw

6

ประกาศอาร์เรย์ใน C และ C ++

type variable_nameโดยปกติแล้วการประกาศตัวแปรเป็นของรูปแบบ คุณสามารถอ่านประกาศเหล่านั้นได้อย่างง่ายดายจากซ้ายไปขวา แต่ก่อนอื่นต้องint foo[size]ดูว่ามันประกาศfooว่าเป็น int แล้วคุณจะอ่านเพิ่มเติมและดูว่า "อาร์เรย์ของจำนวนเต็ม" ประเภท foo int[size] fooอ่านดีขึ้นมาก

และฉันก็เกลียดเมื่อโปรแกรมเมอร์ประกาศตัวชี้เช่นนี้ด้วยเหตุผลที่คล้ายกัน: int *foo. ด้วยเหตุผลบางอย่างที่ฉันยังไม่ได้คิดออกมานั่นเป็นวิธีทั่วไปที่เขียน


1
การประกาศพอยน์เตอร์อีกครั้ง: พวกมันเขียนเช่นนั้นเพราะ ' ' ผูกกับชื่อตัวแปรไม่ใช่ประเภท ดังนั้นint* a, b;* ไม่ประกาศaและbเป็นตัวชี้; เท่านั้นaคือ ดังนั้นควรเขียนเป็นint *a, b;(หรือดีกว่าเขียนเป็นประกาศสองฉบับ)
Steve Melnikoff

จุดดี. มันแย่เกินไปที่*จะไม่ผูกกับประเภท
จาค็อบ

2
และนี่คือสิ่งที่ไม่พูดถึงตัวชี้ฟังก์ชั่น ... void(int) *f;? Nope:void (*f)(int);
หมายเหตุตนเอง - คิดชื่อ

ในปัจจุบัน C ++ นั้นมีความต้องการตัวชี้และอาร์เรย์น้อยมาก
fredoverflow

2
@Steve Melnikoff: แม้ว่าฉันได้ +1 คำตอบนี้แล้วฉันคิดว่าint* a, b;ปัญหาที่คุณกล่าวถึงนั้นมีความสำคัญมาก
j_random_hacker

5

การกำหนดพารามิเตอร์ซ้ำซ้อนใน Java:

HashMap<String,HashMap<String,String>> foo = new HashMap<String, HashMap<String, String>>();

คอมไพเลอร์ชนิดอื่น ๆ ที่คิดว่า fooจะมีพารามิเตอร์อะไร


4
ฉันหวังว่าคุณจะตระหนักถึงการอนุมานประเภท Java (จำกัด )? HashMap<String,HashMap<String,String>> foo = Maps.newHashMap();
finnw

1
Java 7:HashMap<String,HashMap<String,String>> foo = new HashMap<>();
Bart van Heukelom

5
มันสามารถมีรูปแบบใดก็ได้ตามต้องการประเภทจะถูกลบออก ...
กำหนดค่า

ไม่มีการอนุมานประเภทคุณหมายถึงอะไร
missingfaktor

What other type parameterization does the compiler think foo could have?- ไม่ว่าจะด้วยเหตุผลอะไรก็ตามมันเป็นแบบดิบ - ราวกับว่าใครก็ตามที่มีสติสัมปชัญญะจะผสมประเภทดิบและ parametrized
maaartinus

5

เนื่องจากมีคนบ่นแล้วเกี่ยว=กับการเทียบกับ==ให้ฉันชี้ให้เห็นทางเลือกที่เลวร้ายยิ่งกว่า PL / ผมมีทั้งสอง:=และ=, แต่เมื่อบางสิ่งบางอย่างก็คือ "เห็นได้ชัดว่า" งานก็จะให้คุณได้รับไปกับการใช้=ที่จะทำมัน การใช้:=ให้คุณบังคับให้บางสิ่งบางอย่างเป็นการมอบหมายในสถานการณ์ที่คอมไพเลอร์จะตีความว่าเป็นการเปรียบเทียบ

น่าเสียดายที่คอมไพเลอร์ไม่ได้ตัดสินใจเลือกสิ่งที่คุณคาดหวัง ลองพิจารณาตัวอย่างหนึ่งที่เห็นได้ชัด:

A = B = 0;

ตอนนี้สำหรับคนส่วนใหญ่ที่คุ้นเคยกับภาษา "ธรรมดา" ส่วนใหญ่ความหมายของสิ่งนี้ค่อนข้างชัดเจน - กำหนด 0 ให้ทั้ง A และ B. PL / I ค่อนข้างแตกต่าง ... สำหรับเหตุผลที่ผู้ออกแบบ (บ้า) เท่านั้นที่รู้จักภาษานั้นคนแรก=ถูกตีความว่าเป็นงานที่ได้รับมอบหมาย แต่คนที่สอง=ถูกตีความเป็นการเปรียบเทียบ ดังนั้นสิ่งนี้เปรียบเทียบ B เป็น 0 และจากนั้นกำหนดผลลัพธ์ของการเปรียบเทียบนั้นกับ A (ทำตามแบบแผน C ที่ผลลัพธ์ "false" เป็น 0 และ "true" ใน 1)

ดังนั้นถ้า B เป็น 0 ดังนั้น A กลายเป็น 1 มิฉะนั้น A กลายเป็น 0 ในคำอื่น ๆ แทนที่จะกำหนดค่าเดียวกันให้กับ A และ B สิ่งนี้ทำให้แน่ใจได้ว่า A ไม่สามารถมีค่าเดียวกับ B

บรรทัดด้านล่าง: แม้ว่า C สไตล์ / C ++ / PHP แรกดูเหมือนเช่นความเจ็บปวดทางเลือกเป็นเลวร้ายมาก1

1ดีในทางเทคนิคมีอีกทางเลือกหนึ่ง: แบบปาสคาลที่มักจะหมายถึงการเปรียบเทียบและการมอบหมายมักจะต้อง= :=หลังจากใช้สิ่งนั้นไปซักพักมันค่อนข้างชัดเจน (อย่างน้อยสำหรับฉัน) ว่าการมอบหมายนั้นเป็นเรื่องธรรมดามากกว่าการเปรียบเทียบว่าถ้าคุณต้องการ "สิ่ง" เพิ่มเติมเพื่อทำให้ทั้งสองคนเข้าใจผิดคุณควรทำให้งานนั้นสะอาดและเรียบง่าย ต้องใช้ "กรันจ์" พิเศษในการเปรียบเทียบไม่ใช่ในทางกลับกัน


1
ฉันยังเสนอให้ใช้==เพื่อความเท่าเทียมและ:=เพื่อการมอบหมาย ในแบบที่คุณมีมากขึ้นในการพิมพ์ แต่การหลีกเลี่ยงความเหงา=ช่วยหลีกเลี่ยงข้อบกพร่อง
maaartinus

@maartinus: อย่างน้อยผมว่าเสียงเหมือนความเป็นไปได้ที่เลวร้ายที่สุดแน่นอน แต่นั่นคือชีวิต ...
เจอร์รี่โลงศพ

3

Perl

  1. ฉันหวังว่า Perl if($x < 10) do_something();ขอผมเขียน ในขณะที่คุณต้องเขียนว่าเป็นอย่างใดอย่างหนึ่งหรือเป็นdo_something() if($x < 10);if($x < 10) { do_something(); }

9
do_something() if ($x < 10);ไม่เลว
zneak

มันไม่ใช่และในหลาย ๆ กรณีนั้นสะอาดกว่าif(..) ...การบู๊ตเพราะคุณสามารถรับนิพจน์ทั้งหมดเพื่อจัดเรียงทางด้านขวา แต่มีบางครั้งที่ฉันอยากจะพูดif($x < 10) do_something();และก็โชคร้ายที่ Perl ไม่ยอมให้ฉัน
Gaurav

7
มันโชคร้ายจนกระทั่งคุณเขียนif ($x<10) do_something(); and_call_me(); และสงสัยว่าทำไมคุณไม่เคยได้รับสาย ฉันหวังว่า C และครอบครัวจะต้องใช้เครื่องมือจัดฟันเพื่อป้องกันข้อผิดพลาดประเภทนั้น
AShelly

2
@Ashelly: หรือทำไมคุณได้รับสายจริง
zneak

1
@zneak ยกเว้น no elses (ฉันหวังว่ามันจะEXPR1 if COND else EXPR2เหมือนกับงูใหญ่)
Ming-Tang

3

reinterpret_cast<unsigned long>ใน c ++ การดำเนินการนี้มีประโยชน์ในการจัดการกับ API ของต่างประเทศและสร้างความมั่นใจเกี่ยวกับความแม่นยำเชิงตัวเลขทำไมจึงเป็นความเจ็บปวดในการพิมพ์และน่าดู


17
มันน่าเกลียดที่จะเตือนคุณว่าคุณควรพยายามเขียนโค้ดที่ไม่ต้องการมัน :)
greyfade

สำหรับฉันแล้วมันเป็นข้อถกเถียงทางวิทยาศาสตร์คอมพิวเตอร์ที่ดีทางทฤษฎี แต่จากประสบการณ์ของฉันมันมีประโยชน์เกินกว่าที่จะหลีกเลี่ยงได้ (อย่างไรก็ตามประสบการณ์ของฉันส่วนใหญ่เป็นธรรมดา C แบบเก่าดังนั้นฉันอาจมีอคติ)
AShelly

5
ไม่ใช่ข้อโต้แย้ง CS เชิงทฤษฎี: การใช้ a reinterpret_castใน C ++ นั้นเป็นกลิ่นที่รุนแรงมาก 99% ของเวลาที่คุณจะใช้มันมีโอกาสคุณไม่จำเป็นต้องทำ - คุณอาจทำอะไรผิดไป อีก 1% ของเวลาที่คุณกำลังเชื่อมต่อกับ C reinterpret_castจะแบ่งระบบประเภทเพื่อให้ทำงานได้เมื่อไม่สามารถทำได้ นั่นเป็นสิ่งที่ไม่ดี
greyfade

3

สำหรับ ... ในการสร้างใน JavaScript และforeachสร้างใน PHP เมื่อวนลูปกับอาร์เรย์ ทั้งคู่ทำให้การเขียนบั๊กง่ายกว่าโค้ดที่ถูกต้อง


3
ว้าวนั่นเป็นเรื่องโกหก “ กว่ารหัสที่ถูกต้อง” ไปให้พ้น.
Jonathan Sterling

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

foreach ที่มีการเปลี่ยนแปลงการอ้างอิง (และผู้ประกอบการ) เป็นข้อผิดพลาดที่มีชื่อเสียง ...
umlcat

1
ฉันสับสนฉันคิดว่ามันเป็นความรู้ทั่วไปที่ "for..in" การสร้างใน javascript เสีย ... ทำไมเรื่องนี้ถึงเป็นข้อผิดพลาด
lvilnis

2

พอยน์เตอร์ของอาร์เรย์หรืออาร์เรย์ของพอยน์เตอร์ใน C / C ++ ฉันยังสับสนเกี่ยวกับสิ่งเหล่านี้


3
อ่านประเภทข้างหลัง int[]*เป็นตัวชี้ไปยังอาร์เรย์ของจำนวนเต็มและint*[]เป็นอาร์เรย์ของตัวชี้ถึงจำนวนเต็ม ทำงานได้ดีกับconsts เกินไป: int* constเป็นตัวชี้ค่าคงที่จำนวนเต็มในขณะที่const int*และint const*เป็นตัวชี้ไปยังจำนวนเต็มคงที่ (หรือค่าคงที่จำนวนเต็ม)
zneak

@zneak: "จากขวาไปซ้าย" ไม่ทำงานดูกฎ"เกลียวตามเข็มนาฬิกา" / "ข้างใน" ที่กล่าวถึง

หรือเพียงใช้typedefsและไม่มีความสับสน
Billy ONeal

ในปัจจุบัน C ++ นั้นมีความต้องการตัวชี้และอาร์เรย์น้อยมาก
fredoverflow

4
@tchrist: ไม่เป็นความจริง int (*p)[10];ประกาศว่าpเป็นตัวชี้ไปยังอาร์เรย์ 10 ints ถ้าsizeof (int) == 4เช่นนั้นp++จะเพิ่มpขึ้น
40.j_random_hacker


1

Javascript / Java ฯลฯ เท่ากับการเปรียบเทียบเช่นถ้า (a == 1)

ฉันจะเขียนถ้า (a = 1) กี่ครั้ง

ในฐานะมนุษย์ฉันอ่านได้อย่างสมบูรณ์แบบ แต่ล่าม / คอมไพเลอร์ darn พูดว่า "เฮ้ฉันจะมอบหมาย 1 ให้ a แล้วตรวจสอบว่า a เท่ากับ 1 หรือไม่และคุณเชื่อหรือไม่ว่าใช่!

ผลักฉันขึ้นไปบนกำแพง

ถ้า (a == 1) อ่านได้น้อยกว่ามากและผู้แปล / ผู้แปลควรรู้ว่าฉันหมายถึงอะไรอยู่ดี ภาษาที่น้อยกว่าอื่น ๆ (VB) ได้ประสบความสำเร็จในการใช้งานมาหลายร้อยปีแล้ว


อะไรคือสิ่งที่if (a = true)ควรจะหมายความว่าอย่างไร
Tom Hawtin - tackline

2
การมอบหมายไม่ควรส่งคืนค่า บางครั้งมันมีประโยชน์ แต่ในกรณีส่วนใหญ่มันเป็นแค่อาการปวดคอ
กำหนดค่า

ใน Javascript JSLint จะตรวจจับสิ่งนั้นให้คุณ
Zachary K

ปัญหาคือการกำหนดเงื่อนไขให้เป็นประโยชน์ ฉันพบ <tt> ในขณะที่ (element = list-> next ()) </tt> อ่านได้ค่อนข้างชัดเจน ดังนั้นฉันไม่แน่ใจว่าฉันต้องการลบมันไหม
Inca

3
@ ทอม: หมายความว่าคุณไม่เข้าใจบูลีน หากคุณมีความหมายเพียงแค่เขียนif (a == true) if (a)หากคุณมีความหมายa = trueแล้วifงบซ้ำซ้อน
dan04

1

การใช้คำฟุ่มเฟือยในคลาสที่ไม่ระบุชื่อของ Java หวังว่าจะได้รับการแก้ไขในไม่ช้า


ถ้าคุณไม่ต้องการมากกว่าหนึ่งวิธี
Tom Hawtin - tackline

0

structPointer->memberใน C / C ++ อาจดีสำหรับการอ่านรหัสของคนอื่น แต่ฉันไม่ชอบ ตัวละครสองตัวแทนที่จะเป็นหนึ่งเดียว ... เป็นการสิ้นเปลืองพื้นที่!


2
น่าเสียดายที่มันต้องแตกต่างจาก.ซึ่งใช้กับสมาชิกของวัตถุที่ไม่ใช่ตัวชี้ ไวยากรณ์ที่กำกวมไม่ถูกต้อง mmmkay?
greyfade

2
@greyfade: ใช่! เพราะคอมไพเลอร์ไม่สามารถอาจจะใช้กฎของระบบการพิมพ์ที่จะบอกเมื่อคุณใช้ตัวชี้ประเภทการ struct และใช้ dereference โดยปริยาย ไม่นี่มันช่างบ้าจริงๆ! (และยังสามารถให้ข้อความแสดงข้อผิดพลาดเมื่อคุณทำผิด) ไม่มีอะไรคลุมเครือเกี่ยวกับไวยากรณ์ มันเป็นแค่ C ที่ทำให้สมองยุ่งเหยิงตามปกติ เดลฟี่ทำการปรับเปลี่ยนโดยปริยายได้ดีถ้าคุณทำงานในมุมมืดที่ต้องใช้พอยน์เตอร์ - เรคคอร์ดจึงสามารถทำได้อย่างแน่นอนโดยไม่ทำให้โปรแกรมแยกวิเคราะห์สับสน ...
Mason Wheeler

5
@ Mason: สิ่งที่เกี่ยวกับกรณีเช่นshared_ptrที่->เข้าถึงประเภทที่มีอยู่และ.เข้าถึงคุณสมบัติของshared_ptrตัวเอง? ฉันขอโทษ แต่ฉันไม่เห็นด้วยอย่างยิ่งที่นี่
Billy ONeal

2
อาจจะแย่ลง อาจจะเป็น PHP, ที่คุณต้องใช้งาน->ให้กับสมาชิกในการเข้าถึงของอะไร
Carson Myers

1
@ maaartinus: รหัสใด ๆ ที่ต้องอาศัยการเรียงลำดับการดำเนินการที่ไม่ชัดเจนไม่ใช่รหัสที่ฉันจะเขียน
Billy ONeal

0

Scala รหัสหลายบรรทัดในวงเล็บ

ตัวอย่างเช่น

class Foo(
         val bar: String,
         val baz: Int,
         val bing: String,
         val bong: Boolean
 ) extends Model {
   // body here
 }

สิ่งที่คุณได้รับจากมันยอดเยี่ยมจริงๆ มันสร้างคอนสตรัคและ getters และ setters สำหรับคุณ แต่มันก็น่าเกลียดและทำลายแบบจำลองทางจิตทั้งหมดของฉันถึงวิธีการเยื้องรหัสและทำให้ฉันรู้สึกเหมือนฉันอยู่ในแซนวิชแปลกประหลาดกับ Java ในด้านหนึ่งและเสียงกระเพื่อมในอีกด้านหนึ่ง (โอ้เดี๋ยวก่อน ... นั่นเป็นประเด็นของสกาล่า)


ฉันสับสน - คุณหมายถึงส่วนที่อยู่ในวงเล็บ ( val barและต่อไป) หรือส่วนที่อยู่ในเครื่องหมายปีกกา (ส่วนต่อไปนี้extends Model) หรือไม่ (ไม่มีรหัสในวงเล็บ)
Billy ONeal

3
ส่วนในวงเล็บ ฉันเป็นคนอังกฤษ. เราอ้างถึงสิ่งเหล่านี้ว่าเป็นวงเล็บเหลี่ยม, damnit, เพราะในสถานการณ์นั้นพวกเขาไม่ได้ทำหน้าที่เป็นผู้ปกครอง
Tom Morris

2
มันดูไม่เลวเลยถ้าเยื้องด้วยวิธีนี้: pastebin.com/h9qC8XGg
missingfaktor

ฉันคิดว่ามันสามารถอ่านได้ง่ายขึ้นในการเขียนพารามิเตอร์ Constructor เหล่านี้ในแนวนอนโดยเฉพาะเมื่อฉันมีเพียงไม่กี่พารามิเตอร์
MJP

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