คุณจะเห็นการใช้ Trilean (True, False, ??) ใด ๆ [ปิด]


22

บางครั้งฉันมีฟังก์ชั่นที่ควรกลับจริงหรือเท็จ แต่บางครั้งค่าสามค่าที่เป็นไปได้นั้นสมเหตุสมผลกว่า

ในบางกรณีภาษาเหล่านี้จะได้รับการจัดการด้วยจำนวนเต็มหรือมีข้อยกเว้น

สำหรับตัวอย่างที่คุณต้องการจัดการอายุของผู้ใช้ถ้าเขาอายุมากกว่า 18 ปี และคุณมีฟังก์ชั่นเช่นนี้

if(user.isAdult(country_code)){
     //Go On
}else{
     // Block access or do nothing
}

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

switch(user.isAdult()){
    case true:
        // go on
        break;
    case undetermined:
        //Inform user birthday is incomplete
    case false:
        //Block access
}

อย่างที่ฉันบอกว่าเราสามารถจัดการกับมันด้วย Exceptions และ Int แต่ฉันคิดว่ามันค่อนข้างเซ็กซี่ที่จะมีการฝังตัวจริงที่เป็นเท็จและไม่ถูก จำกัด ในภาษาแทนที่จะใช้ค่าคงที่ที่กำหนดไว้ที่บ้าน


15
หน้าที่เชื่อมโยง TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear

2
@ แอนนาเลียร์: ประณามคุณเอาชนะฉันไป ^^
gablin

3
แกบลิน: ประณามคุณยังตีฉันให้บ่นเกี่ยวกับแอนนา
281377

1
ฮึฉันอยากได้ T, F, FNF ด้วย! shakes fist
Mike M.

4
@gablin, @ammoQ, @Mike M: ขออภัย :)
Adam Lear

คำตอบ:


33

สิ่งนี้สามารถจัดการได้ด้วย enums จำนวนเต็มสัญลักษณ์ (เช่น Lisp, Ruby) ประเภท nullable (ใช้ null เป็นสถานะไม่แน่นอน) ประเภทตัวเลือก (เช่น ML) หรือโครงสร้างที่คล้ายกันขึ้นอยู่กับภาษาของคุณ

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


null ใน C / C ++ ควรเท่ากับ false ในกรณีเหล่านี้คุณต้องส่งคืน -1 ฉันคิดว่าสถานะบึกบึนค่อนข้างบ่อย แต่ได้รับการปฏิบัติต่างไปจากเดิมเสมอเพราะไวยากรณ์นี้ไม่มีอยู่จริง ใน java ฟังก์ชั่นบูลีนไม่สามารถส่งคืนสิ่งอื่นนอกจากความจริงหรือเท็จสำหรับฟังก์ชั่นบูลีน ดังนั้นคุณถูกบังคับให้ใช้ประเภทและเอกสารที่แตกต่างกันถึงค่าที่ส่งคืน
Loïc Faure-Lacroix

@Sybiam - มีอะไรผิดปกติกับการใช้ชนิดที่แตกต่างกันตามความเหมาะสม อย่างที่ฉันบอกว่าฉันเห็นข้อโต้แย้งเกี่ยวกับประเภท trinary แต่ฉันไม่เห็นว่ามันจะถูกเพิ่มเข้าไปในภาษาที่มีอยู่ในเวลาไม่นาน
ChrisF

6
@Sybiam: ใน Java nullคุณสามารถบูลีนกลับซึ่งสามารถ ใน C / C ++ คุณสามารถคืนค่า enum ได้
Macneil

นี่คือความบ้า!
Loïc Faure-Lacroix

2
@Macneil อาจจะเป็น Sparta?
syockit

5

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

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}

2
หากข้อมูลไม่ถูกต้องสามารถขอให้ผู้ใช้แก้ไขซึ่งแตกต่างจากที่ยังไม่บรรลุนิติภาวะซึ่งคุณไม่ได้ขอให้บุคคลนั้นป้อนอายุใหม่ นี่คือพฤติกรรมที่แตกต่าง 2 เพื่อยกตัวอย่างบางไซต์โซเชียลให้คุณป้อนวันเกิดไม่สมบูรณ์เพื่อความเป็นส่วนตัว
Loïc Faure-Lacroix

2
ฉันคิดว่าควรทำการตรวจสอบความถูกต้องในส่วน / ส่วนอื่นของรหัส ตรวจสอบข้อมูลก่อนแล้วจึงดำเนินการกับมัน
Michael K

1
@Sybiam: โดยทั่วไปแอพพลิเคชั่นจะไม่ขอข้อมูลแบบจับจดเมื่อพวกเขาต้องการมัน คุณสามารถ.isAdult()สอบถามผู้ใช้เองได้หากเป็นสิ่งที่คุณต้องการจริงๆและนั่นจะทำงานได้ดีขึ้น
David Thornley

5

จริงเท็จไม่ทราบ

ใช่ไม่บางที

ใน C # คุณสามารถใช้บูลที่เป็นโมฆะได้ (คุณอาจหดตัวด้วยความสยองขวัญในตอนนี้)

ใน MS-SQL คุณสามารถใช้ฟิลด์บิตเป็นโมฆะได้ (เหมือนกัน)


2
ปัญหาของบูลีนที่ไม่สามารถทำได้นั้นไม่ใช่ว่าพวกมันจะมีค่าเป็นโมฆะเท่าที่คนส่วนใหญ่ (รวมอยู่ด้วย) ไม่รู้เรื่องตรรกะสามค่า สิ่งที่หนึ่งสำหรับ starters: Scientopia.org/blogs/goodmath/2010/08/24/ …
Frank Shearar

จริง / เท็จ / ไม่มี
Lennart Regebro

2
สิ่งที่ตลกคือผู้คนจำนวนมากเข้าใจเลขฐานสองฐานแปดและเลขฐานสิบหก แต่ไม่สามารถห่อความคิดของพวกเขารอบสาม ทำไมถึงเป็นอย่างนั้น? สิ่งเดียวกันเพียงแค่ฐานสาม ... ที่จะแก้ปัญหาตรรกะค่าสาม
Michael K

5
unknownคนส่วนใหญ่ก็มีความกลัวของที่
dan04

2

ใน C ++ สิ่งนี้สามารถจัดการได้ด้วย non- boolreturn type หรือโดยการโยน exception enumถ้าคุณต้องการพิมพ์กลับสามมูลค่าให้ใช้ มันไม่เซ็กซี่ แต่ก็ใช้งานได้และสิ่งที่สำคัญกว่านั้นคือคุณสามารถทำได้โดยไม่ทำให้ภาษาของเรายุ่ง

มีboolสามค่าจะทำให้เกิดปัญหา คุณจะจัดการbool foo; ... if (foo)...อย่างไรสมมติว่าfooอาจมีค่าใดค่าหนึ่งในสามค่า มีข้อได้เปรียบในการมีboolตัวแปรที่แม่นยำfooและ!fooเป็นจริงตลอดเวลา ช่วยให้เหตุผลเกี่ยวกับโปรแกรม

ตรวจสอบสิ่งที่ผู้คนทำในการประมวลผลเชิงตัวเลขเมื่อพวกเขาอาจได้รับNaNค่า มันซับซ้อน. ฉันไม่ต้องการทำตามเพื่อประมวลผลบูลีนธรรมดา

หากคุณต้องการ.isAdult()ที่จะจัดการกับข้อมูลที่ไม่เพียงพอมีมันทำอย่างนั้นภายในและจากนั้นกลับมาอย่างใดอย่างหนึ่งหรือtrue falseมิฉะนั้นทุกครั้งที่คุณใช้งานคุณจำเป็นต้องตรวจสอบรหัสส่งคืนก่อนที่จะทำสิ่งใดและทำวิธีจัดการกับมัน มันหมายความว่าคุณต้องตรวจสอบเอกสารเพื่อดูว่าฟังก์ชั่นทำในสิ่งที่ชื่อของมันบอกหรือไม่และนั่นจะเป็นหายนะต่อการอ่านได้


2

ความคิดมีประโยชน์มาก มีทั้งสนามที่ทุ่มเทให้กับการจัดการกับความไม่แน่นอนที่เรียกว่าเป็นระบบ Fuzzy Logic

โชคดีสำหรับเราโปรแกรมเมอร์คุณสามารถใช้ตรรกะคลุมเครือด้วยคุณสมบัติภาษามาตรฐาน

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

มีวิธีอื่น ๆ ทุกชนิดที่จะไม่แน่นอน คำถามดังกล่าวรวมถึง:

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

คำถามเหล่านั้นจำนวนมากสามารถจัดการกับการใช้ความน่าจะเป็นในช่วง 0.0 (เท็จ) ถึง 1.0 (จริง) และใช้คณิตศาสตร์จุดลอย

นักเคมีคอมพิวเตอร์และนักวิทยาศาสตร์คอมพิวเตอร์ชื่อ David E. Shaw ใช้สิ่งนี้กับ Wall Street และตอนนี้มีมูลค่าประมาณ 2.5 พันล้านเหรียญ ใช่มันมีประโยชน์ :-)


1

หลายปีที่ผ่านมาฉันเล่นกับอัลกอริทึมบางตัวที่ออกมาเพื่อกำหนดค่าความเชื่อ เป็นคนที่สนุกสนาน ในที่สุดสิ่งที่ฉันได้รับจากมันก็คือบูลีนมักจะเป็นแบบที่วางแผนไว้ จริง ๆ ควรเป็นค่า trilean จริง / เท็จ / อื่น ๆ ในการทดลองที่ดูเหมือนจะนำไปสู่รหัส "ดีที่สุด" สำหรับฉันในเวลานั้น ฉันพังและทำในสิ่งที่คนอื่นทำในขณะที่คิดว่ามันง่ายกว่ากันมากแค่ไหนถ้าเราเลิกทำสิ่งต่าง ๆ ในแบบเดิม ... :-)


0

คำสั่ง Case หรือ Switch จะทำงานได้ดีสำหรับสิ่งนี้ แต่โดยใช้จำนวนเต็มเพื่อจัดการกับสวิตช์โดยพลการ

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


0

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

user.isAdult(new OnlyAllowAdultsToLogin())

โดยที่OnlyAllowAdultsToLoginStrategyใช้อินเตอร์เฟส:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}

อะไรvoid userIsAdult()ทำอย่างไร คุณอาจหมายถึงbool userIsAdult()?
Timwi

0

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


0

C มีคุณสมบัตินี้ใช้งานในฟังก์ชั่นห้องสมุดส่วนใหญ่ เช่น strcmp เปรียบเทียบ 2 สตริงและส่งคืน 0 หากพวกเขาเหมือนกัน 1 (เช่นจำนวนเต็มบวกใด ๆ ) หากค่าที่ 1 มากกว่า 'มากกว่า' ที่ 2 และ -1 (เช่นลบจำนวนเต็มใด ๆ ) หากค่าที่สองมากกว่าครั้งแรก .

วิธีการเดียวกันนี้สามารถใช้ที่อื่นได้ + / 0 / - เป็นไตรสถานะของคุณ นอกจากนี้ยังช่วยให้คุณสามารถดำเนินการตรรกะบูลีนกับค่าถ้าคุณรู้ว่า 0 ถ้าเท็จและค่าอื่น ๆ เป็นจริง


0

สำหรับ C ++ Boost จะใช้Tribool ที่อธิบายดังนี้:

คลาส tribool ทำหน้าที่เหมือนกับชนิดบูลในตัว แต่สำหรับตรรกะบูลีน 3 สถานะ สามสถานะเป็นจริงเท็จและไม่แน่นอนโดยที่สองสถานะแรกเทียบเท่ากับของประเภท C ++ bool และสถานะสุดท้ายแสดงถึงค่าบูลีนที่ไม่รู้จัก (ซึ่งอาจเป็นจริงหรือเท็จเราไม่รู้)


-1

ช่องทำเครื่องหมาย VB6 มีความสามารถนี้ ค่าช่องทำเครื่องหมายสามารถเป็น 0 = ปิด, 1 = เปิด, 2 = เป็นสีเทา

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