Ném ngoại lệ hoặc để mã thất bại


52

Tôi tự hỏi nếu có bất kỳ ưu và nhược điểm chống lại phong cách này:

private void LoadMaterial(string name)
{
    if (_Materials.ContainsKey(name))
    {
        throw new ArgumentException("The material named " + name + " has already been loaded.");
    }

    _Materials.Add(
        name,
        Resources.Load(string.Format("Materials/{0}", name)) as Material
    );
}

Phương pháp đó, đối với mỗi name, chỉ được chạy một lần. _Materials.Add()sẽ ném một ngoại lệ nếu nó sẽ được gọi nhiều lần cho cùng một name. Là người bảo vệ của tôi, kết quả là, hoàn toàn dư thừa, hoặc có một số lợi ích ít rõ ràng hơn?

Đó là C #, Unity, nếu có ai quan tâm.


3
Điều gì xảy ra nếu bạn tải một vật liệu hai lần mà không có người bảo vệ? Có _Materials.Addném một ngoại lệ?
dùng253751

2
Trên thực tế tôi đã đề cập đến trong một ngoại lệ: P
async

9
Ghi chú bên: 1) Cân nhắc sử dụng string.Formatnối chuỗi trên để xây dựng thông báo ngoại lệ. 2) chỉ sử dụng asnếu bạn mong đợi diễn viên thất bại và kiểm tra kết quả null. Nếu bạn mong muốn luôn luôn có được một Material, sử dụng một diễn viên như thế (Material)Resources.Load(...). Một ngoại lệ cast rõ ràng dễ gỡ lỗi hơn một ngoại lệ tham chiếu null xảy ra sau này.
CodeInChaos

3
Trong trường hợp cụ thể này, người gọi của bạn cũng có thể tìm thấy một người bạn đồng hành LoadMaterialIfNotLoadedhoặc ReloadMaterial(tên này có thể sử dụng cải tiến) hữu ích.
jpmc26

1
Một lưu ý khác: Mẫu này được chấp nhận khi đôi khi thêm một mục vào danh sách. Tuy nhiên, không sử dụng mẫu này để điền vào toàn bộ danh sách vì bạn sẽ gặp phải tình huống O (n ^ 2) trong đó với danh sách lớn bạn sẽ gặp phải các vấn đề về hiệu suất. Bạn sẽ không nhận thấy nó ở 100 mục nhưng ở 1000 mục bạn chắc chắn và ở 10.000 mục đó sẽ là một nút cổ chai lớn.
Pieter B

Câu trả lời:


109

Lợi ích là ngoại lệ "tùy chỉnh" của bạn có thông báo lỗi có ý nghĩa đối với bất kỳ ai gọi chức năng này mà không biết cách thức triển khai (trong tương lai có thể là bạn!).

Cấp, trong trường hợp này, họ có thể đoán được ngoại lệ "tiêu chuẩn" nghĩa là gì, nhưng bạn vẫn nói rõ rằng họ đã vi phạm hợp đồng của bạn, thay vì vấp phải một số lỗi lạ trong mã của bạn.


3
Đồng ý. Gần như luôn luôn tốt hơn để ném một ngoại lệ cho một vi phạm điều kiện tiên quyết.
Frank Hileman

22
"Lợi ích là ngoại lệ" tùy chỉnh "của bạn có thông báo lỗi có ý nghĩa đối với bất kỳ ai gọi chức năng này mà không biết cách thức triển khai (trong tương lai có thể là bạn!)." Lời khuyên hàng đầu.
async

2
"Rõ ràng là tốt hơn so với ngầm." - Zen of Python
jpmc26

4
Ngay cả khi lỗi do lỗi _Materials.Addkhông phải là lỗi bạn muốn truyền đến người gọi, tôi nghĩ phương pháp này để xác định lại lỗi là không hiệu quả. Đối với mỗi cuộc gọi thành côngLoadMaterial (hoạt động bình thường), bạn sẽ thực hiện cùng một bài kiểm tra độ tỉnh táo hai lần , LoadMaterialsau đó lại thực hiện _Materials.Add. Nếu nhiều lớp được bọc, mỗi lớp sử dụng cùng một kiểu, bạn thậm chí có thể có nhiều lần hơn cùng một bài kiểm tra.
Marc van Leeuwen

15
... Thay vào đó hãy xem xét lao vào _Materials.Addvô điều kiện, sau đó bắt lỗi tiềm ẩn và trong trình xử lý ném một lỗi khác. Công việc làm thêm bây giờ chỉ được thực hiện trong các trường hợp sai sót, đường dẫn thực thi đặc biệt mà bạn không thực sự lo lắng về hiệu quả.
Marc van Leeuwen

100

Tôi đồng ý với câu trả lời của Ixrec . Tuy nhiên, bạn có thể muốn xem xét một phương án thứ ba: làm cho hàm không hoạt động. Nói cách khác, trở về sớm thay vì ném một ArgumentException. Điều này thường được ưu tiên hơn nếu bạn thường bị buộc phải kiểm tra xem nó đã được tải chưa trước khi gọi LoadMaterialmỗi lần. Bạn càng có ít điều kiện tiên quyết, càng ít tải nhận thức về lập trình viên.

Ném một ngoại lệ sẽ tốt hơn nếu đó thực sự là một lỗi lập trình viên, trong đó nó phải rõ ràng và được biết đến vào thời gian biên dịch nếu tài liệu đã được tải, mà không phải kiểm tra trong thời gian chạy trước khi gọi.


2
Mặt khác, có một chức năng thất bại âm thầm có thể gây ra hành vi không mong muốn dẫn đến khó tìm thấy lỗi xảy ra sau này.
Philipp

30
@Philipp chức năng sẽ không thất bại âm thầm. Trở nên bình thường có nghĩa là chạy nó nhiều lần có tác dụng tương tự như chạy nó một lần. Nói cách khác, nếu tài liệu đã được tải, thì thông số kỹ thuật của chúng tôi ("tài liệu nên được tải") đã được thỏa mãn, vì vậy chúng tôi không cần phải làm gì cả. Chúng tôi chỉ có thể trở lại.
Warbo

8
Tôi thích điều này hơn, thực sự. Tất nhiên, tùy thuộc vào các ràng buộc được đưa ra bởi các yêu cầu ứng dụng, điều này có thể sai. Sau đó, một lần nữa, tôi là một fan hâm mộ tuyệt đối của các phương pháp idempotent.
FP

6
@Philipp nếu chúng tôi nghĩ về nó LoadMaterialcó các ràng buộc sau: "Sau khi gọi nó, vật liệu luôn được tải và số lượng vật liệu được tải không giảm". Ném một ngoại lệ cho ràng buộc thứ ba "Tài liệu không thể được thêm hai lần" có vẻ ngớ ngẩn và phản trực giác đối với tôi. Làm cho hàm idempotent làm giảm sự phụ thuộc của mã vào trạng thái ứng dụng và trạng thái ứng dụng. Có vẻ như một chiến thắng kép cho tôi.
Benjamin Gruenbaum

7
Tôi thích ý tưởng này, nhưng đề xuất một thay đổi nhỏ: trả về một boolean phản ánh xem có bất cứ thứ gì đã được tải hay không. Nếu người gọi thực sự quan tâm đến logic ứng dụng, họ có thể kiểm tra điều đó và đưa ra một ngoại lệ.
dùng949300

8

Câu hỏi cơ bản mà bạn phải đặt ra là: Bạn muốn giao diện cho chức năng của mình là gì? Cụ thể, điều kiện _Materials.ContainsKey(name)là điều kiện tiên quyết của hàm?

Nếu nó không phải là điều kiện tiên quyết, hàm phải cung cấp kết quả được xác định rõ cho tất cả các giá trị có thể có name. Trong trường hợp này, ngoại lệ được ném nếu namekhông phải là một phần của _Materialsgiao diện của hàm. Điều đó có nghĩa là nó cần phải là một phần của tài liệu giao diện và nếu bạn quyết định thay đổi ngoại lệ đó trong tương lai, đó sẽ là một thay đổi giao diện phá vỡ .

Câu hỏi thú vị hơn là những gì xảy ra nếu nó là một điều kiện tiên quyết. Trong trường hợp đó, điều kiện tiên quyết trở thành một phần của giao diện chức năng, nhưng cách mà một chức năng hoạt động khi điều kiện này bị vi phạm không nhất thiết là một phần của giao diện.

Trong trường hợp này, cách tiếp cận mà bạn đã đăng, kiểm tra các vi phạm tiền điều kiện và báo cáo lỗi, là những gì được gọi là lập trình phòng thủ . Lập trình phòng thủ tốt ở chỗ nó thông báo cho người dùng sớm khi họ mắc lỗi và gọi hàm này bằng một đối số không có thật. Điều tồi tệ là nó làm tăng đáng kể gánh nặng bảo trì, vì mã người dùng có thể phụ thuộc vào chức năng xử lý các vi phạm tiền điều kiện theo một cách nhất định. Đặc biệt, nếu bạn thấy rằng kiểm tra thời gian chạy sẽ trở thành nút cổ chai hiệu năng trong tương lai (không thể xảy ra đối với trường hợp đơn giản như vậy, nhưng khá phổ biến đối với các điều kiện tiên quyết phức tạp hơn), bạn có thể không còn có thể loại bỏ nó.

Nó chỉ ra rằng những bất lợi đó có thể rất đáng kể, điều này đã tạo ra một loại tiếng xấu trong lập trình. Tuy nhiên, mục tiêu ban đầu vẫn còn hiệu lực: Chúng tôi muốn người dùng chức năng của chúng tôi thông báo sớm khi họ mắc lỗi.

Do đó, nhiều nhà phát triển hiện nay đề xuất một cách tiếp cận hơi khác nhau cho các loại vấn đề này. Thay vì ném một ngoại lệ, họ sử dụng một cơ chế giống như khẳng định để kiểm tra các điều kiện tiên quyết. Đó là, các điều kiện tiên quyết có thể được kiểm tra trong các bản dựng gỡ lỗi để hỗ trợ người dùng bắt lỗi sớm, nhưng chúng không phải là một phần của giao diện chức năng. Sự khác biệt có vẻ tinh tế thoạt nhìn, nhưng nó có thể tạo ra sự khác biệt rất lớn trong thực tế.

Về mặt kỹ thuật, gọi một hàm với các điều kiện tiên quyết bị vi phạm là hành vi không xác định. Nhưng việc thực hiện có thể quyết định phát hiện những trường hợp đó và thông báo cho người dùng ngay nếu điều đó xảy ra. Rất tiếc, các trường hợp ngoại lệ không phải là một công cụ tốt để thực hiện điều này, vì mã người dùng có thể phản ứng với chúng và do đó có thể bắt đầu dựa vào sự hiện diện của chúng.

Để được giải thích chi tiết về các vấn đề với phương pháp phòng thủ cổ điển, cũng như có thể triển khai để kiểm tra điều kiện tiên quyết theo kiểu khẳng định, hãy tham khảo chương trình Phòng thủ lập trình của John Lakos được thực hiện ngay từ CppCon 2014 ( Slides , Video ).


4

Đã có một vài câu trả lời ở đây, nhưng đây là câu trả lời có tính đến Unity3D (câu trả lời rất cụ thể đối với Unity3D, tôi sẽ làm hầu hết những điều này rất khác nhau trong hầu hết các bối cảnh):

Nói chung, Unity3D không sử dụng ngoại lệ theo truyền thống. Nếu bạn ném một ngoại lệ vào Unity3D, thì không có gì giống như trong ứng dụng .NET trung bình của bạn, cụ thể là nó sẽ không dừng chương trình, hầu hết bạn có thể định cấu hình trình chỉnh sửa để tạm dừng. Nó sẽ chỉ được đăng nhập. Điều này có thể dễ dàng đưa trò chơi vào trạng thái không hợp lệ và tạo hiệu ứng xếp tầng khiến các lỗi khó theo dõi. Vì vậy, tôi muốn nói trong trường hợp của Unity, cho phép Addném một ngoại lệ là một lựa chọn đặc biệt không mong muốn.

Nhưng trong việc kiểm tra tốc độ của các ngoại lệ không phải là trường hợp tối ưu hóa sớm trong một số trường hợp vì cách Mono hoạt động trong Unity trên một số nền tảng. Trên thực tế, Unity3D trên iOS hỗ trợ một số tối ưu hóa tập lệnh nâng cao và các ngoại lệ bị vô hiệu hóa * là tác dụng phụ của một trong số chúng. Đây thực sự là một cái gì đó để xem xét bởi vì những thiên đường tối ưu hóa đã được chứng minh rất có giá trị đối với nhiều người dùng, cho thấy một trường hợp thực tế để xem xét việc giới hạn việc sử dụng các ngoại lệ trong Unity3D. (* ngoại lệ được quản lý từ công cụ, không phải mã của bạn)

Tôi muốn nói rằng trong Unity bạn có thể muốn có một cách tiếp cận chuyên biệt hơn. Trớ trêu thay, một câu trả lời rất được bình chọn tại thời điểm viết bài này , cho thấy một cách tôi có thể thực hiện một cái gì đó như thế này cụ thể trong bối cảnh của Unity3D (ở một nơi khác như thế này thực sự không thể chấp nhận được, và ngay cả trong Unity, nó khá không phù hợp).

Một cách tiếp cận khác mà tôi xem xét là thực sự không chỉ ra lỗi do người gọi quan tâm, mà là sử dụng các Debug.LogXXchức năng. Bằng cách đó, bạn có được hành vi tương tự như ném một ngoại lệ chưa được xử lý (vì cách Unity3D xử lý chúng) mà không mạo hiểm đặt một cái gì đó vào trạng thái lạ xuống dòng. Ngoài ra hãy xem xét nếu đây thực sự là một lỗi (Việc cố gắng tải cùng một tài liệu hai lần có nhất thiết là một lỗi trong trường hợp của bạn không? Hoặc đây có thể là trường hợp Debug.LogWarningđược áp dụng nhiều hơn).

Và liên quan đến việc sử dụng những thứ như Debug.LogXXhàm thay vì ngoại lệ, bạn vẫn phải xem xét điều gì xảy ra khi một ngoại lệ sẽ được ném từ thứ gì đó trả về giá trị (như GetM vật liệu). Tôi có xu hướng tiếp cận điều này bằng cách chuyển null cùng với việc ghi lại lỗi ( một lần nữa, chỉ trong Unity ). Sau đó, tôi sử dụng kiểm tra null trong MonoBehaviors của mình để đảm bảo mọi phụ thuộc như vật liệu không phải là giá trị null và vô hiệu hóa MonoBehavior nếu có. Một ví dụ cho một hành vi đơn giản đòi hỏi một vài phụ thuộc là như thế này:

    public void Awake()
    {
        _inputParameters = GetComponent<VehicleInputParameters>();
        _rigidbody = GetComponent<Rigidbody>();
        _rigidbodyTransform = _rigidbody.transform;
        _raycastStrategySelector = GetComponent<RaycastStrategySelectionBehavior>();

        _trackParameters =
            SceneManager.InstanceOf.CurrentSceneData.GetValue<TrackParameters>();

        this.DisableIfNull(() => _rigidbody);
        this.DisableIfNull(() => _raycastStrategySelector);
        this.DisableIfNull(() => _inputParameters);
        this.DisableIfNull(() => _trackParameters);
    }

SceneData.GetValue<>tương tự như ví dụ của bạn ở chỗ nó gọi một hàm trên từ điển đưa ra một ngoại lệ. Nhưng thay vì ném một ngoại lệ, nó sử dụng Debug.LogErrormột dấu vết ngăn xếp như một ngoại lệ bình thường và trả về null. Các kiểm tra theo sau * sẽ vô hiệu hóa hành vi thay vì để nó tiếp tục tồn tại ở trạng thái không hợp lệ.

* các kiểm tra trông như thế bởi vì một người trợ giúp nhỏ tôi sử dụng để in ra một thông báo được định dạng khi nó vô hiệu hóa đối tượng trò chơi **. Kiểm tra null đơn giản với ifcông việc ở đây (** séc của người trợ giúp chỉ được biên dịch trong các bản dựng Debug (như xác nhận). Sử dụng lambdas và các biểu thức như thế trong Unity có thể gây ảnh hưởng đến hiệu suất)


1
+1 để thêm một số thông tin thực sự mới vào đống. Tôi đã không mong đợi đó.
Ixrec

3

Tôi thích hai câu trả lời chính, nhưng muốn đề xuất rằng tên hàm của bạn có thể được cải thiện. Tôi đã quen với Java, vì vậy YMMV, nhưng phương thức "thêm" nên, IMO, không ném Ngoại lệ nếu mục đó đã có sẵn. Nó sẽ thêm mục một lần nữa , hoặc, nếu đích là Set, không làm gì cả. Vì đó không phải là hành vi của Vật liệu. Thêm vào đó, nên đổi tên thành TryPut hoặc AddOnce hoặc AddOrThrow hoặc tương tự.

Tương tự, LoadM vật liệu của bạn nên được đổi tên thành Load IfAbsent hoặc Put hoặc TryLoad hoặc LoadOrThrow (tùy thuộc vào việc bạn sử dụng câu trả lời # 1 hoặc # 2) hay một số thứ khác.

Thực hiện theo các quy ước đặt tên C # Unity bất kể chúng là gì.

Điều này sẽ đặc biệt hữu ích nếu bạn có các hàm AddFoo và LoadBar khác, nơi cho phép tải cùng một thứ hai lần. Không có tên rõ ràng, các nhà phát triển sẽ thất vọng.


Có một sự khác biệt betweeen C # Dictionary.Add () semantics (xem msdn.microsoft.com/en-us/l Library / k7z0zy8k% 28v = vs.110% 29.aspx ) và ngữ nghĩa Java Collection.add () (xem tài liệu. oracle.com/javase/8/docs/api/java/util/ Khăn ). C # trả về void và ném ngoại lệ. Trong khi đó, Java trả về bool và thay thế giá trị được lưu trữ trước đó bằng giá trị mới hoặc đưa ra một ngoại lệ khi phần tử mới không thể được thêm vào.
Kasper van den Berg

Kasper - cảm ơn, và thú vị. Làm thế nào để bạn thay thế một giá trị trong Từ điển C #? (Tương đương với một Java đặt ()). Đừng thấy một phương thức được xây dựng trên trang đó.
dùng949300

câu hỏi hay, người ta có thể làm Dictionary.Remove () (xem msdn.microsoft.com/en-us/l Library / bb356469% 28v = vs.110% 29.aspx ) theo sau là Dictionary.Add () (xem msdn.microsoft .com / en-us / library / bb338565% 28v = vs.110% 29.aspx ), nhưng điều này có vẻ hơi khó xử.
Kasper van den Berg

@ user949300 dictionary [key] = value thay thế mục nhập nếu nó đã tồn tại
Rupe

@Rupe và có lẽ ném một cái gì đó nếu nó không. Tất cả dường như rất khó xử với tôi. Hầu hết các khách hàng thiết lập dict không quan tâm wheteher một mục ở đó, họ chỉ quan tâm rằng, sau khi mã thiết lập của họ, nó ở đó. Điểm một cho API Bộ sưu tập Java (IMHO). PHP cũng lúng túng với các dicts, đó là một sai lầm khi đi theo tiền lệ đó.
dùng949300

3

Tất cả các câu trả lời thêm ý tưởng có giá trị, tôi muốn kết hợp chúng:

Quyết định về ngữ nghĩa dự kiến ​​và dự kiến ​​của LoadMaterial()hoạt động. Ít nhất các tùy chọn sau tồn tại:

  • Một điều kiện tiên quyết về nameLoadedM vật liệu : →

    Khi điều kiện tiên quyết bị vi phạm, ảnh hưởng của LoadMaterial()không được chỉ định (như trong câu trả lời của ComicSansMS ). Điều này cho phép hầu hết tự do trong việc thực hiện và thay đổi trong tương lai LoadMaterial(). Hoặc là,

  • hiệu ứng của việc gọi LoadMaterial(name)với nameLoadedM vật liệu được chỉ định; hoặc:

Khi đã quyết định về ngữ nghĩa, bạn phải chọn một triển khai. Các tùy chọn và cân nhắc sau đây khi đề xuất:

  • Ném một ngoại lệ tùy chỉnh (theo đề xuất của Ixrec ) →

    Lợi ích là ngoại lệ "tùy chỉnh" của bạn có thông báo lỗi có ý nghĩa đối với bất kỳ ai gọi chức năng này - IxrecUser16547

    • Để tránh chi phí liên tục kiểm tra nameLoadedMaterials bạn có thể làm theo Marc van Leeuwen của tư vấn:

      ... Thay vào đó hãy xem xét việc lao vào _M vật liệu. Thêm vô điều kiện, sau đó bắt lỗi tiềm ẩn và trong trình xử lý ném một lỗi khác.

  • Hãy để Dictionay. Thêm ngoại lệ →

    Mã ném ngoại lệ là dư thừa. - Jon Raynor

    Mặc dù, hầu hết các cử tri đồng ý nhiều hơn với Ixrec

    Lý do bổ sung để chọn thực hiện này là:

    • người gọi đã có thể xử lý các ArgumentExceptiontrường hợp ngoại lệ và
    • để tránh mất thông tin ngăn xếp.

    Nhưng nếu hai lý do này quan trọng, bạn cũng có thể rút ra ngoại lệ tùy chỉnh của mình ArgumentExceptionvà sử dụng bản gốc làm ngoại lệ được xâu chuỗi.

  • Làm cho LoadMaterial()idempotent là anwser của Karl Bielefeldt và được nâng cấp thường xuyên nhất (75 lần).

    Các tùy chọn thực hiện cho hành vi này:

    • Kiểm tra với Dictionary.ContainsKey ()

    • Luôn gọi Dictionary.Add () bắt ArgumentExceptionnó ném khi khóa cần chèn đã tồn tại và bỏ qua ngoại lệ đó. Tài liệu cho rằng bỏ qua ngoại lệ là những gì bạn định làm và tại sao.

      • Khi LoadMaterials()(hầu như) luôn được gọi một lần cho mỗi lần name, điều này sẽ tránh chi phí liên tục kiểm tra nameLoadedM vật liệu cf Marc van Leeuwen . Tuy nhiên,
      • khi LoadedMaterials()thường được gọi nhiều lần cho cùng một lần name, điều này phải chịu chi phí (đắt đỏ) khi ném ArgumentExceptionvà xếp chồng lên nhau.
    • Tôi nghĩ rằng đã tồn tại một sự TryAddtương tự đối xứng với TryGet () sẽ cho phép bạn tránh việc ném ngoại lệ đắt tiền và ngăn chặn các cuộc gọi thất bại với Dictionary.Add.

      Nhưng sự đối TryAddxứng này dường như không tồn tại.


1
+1 vì là câu trả lời toàn diện nhất. Điều này có thể vượt xa những gì OP ban đầu sau đó, nhưng đó là một bản tóm tắt hữu ích của tất cả các tùy chọn.
Ixrec

1

Mã ném ngoại lệ là dư thừa.

Nếu bạn gọi:

_M vật liệu. Thêm (tên, Tài nguyên. Tải (chuỗi.Format ("Vật liệu / {0}", tên)) làm Tài liệu

với cùng một chìa khóa, nó sẽ ném

System.ArgumentException

Thông báo sẽ là: "Một mục có cùng khóa đã được thêm vào."

Các ContainsKeykiểm tra là không cần thiết vì về cơ bản hành vi tương tự được thực hiện mà không có nó. Mục duy nhất khác biệt là thông điệp thực tế trong trường hợp ngoại lệ. Nếu có lợi ích thực sự từ việc có một thông báo lỗi tùy chỉnh, thì mã bảo vệ có một số giá trị.

Nếu không, tôi có thể sẽ tái cấu trúc bảo vệ trong trường hợp này.


0

Tôi nghĩ rằng đây là một câu hỏi về thiết kế API hơn là một câu hỏi quy ước mã hóa.

Kết quả mong đợi (hợp đồng) của cuộc gọi là gì:

LoadMaterial("wood");

Nếu người gọi có thể mong đợi / được đảm bảo rằng sau khi gọi phương thức này, vật liệu "gỗ" được tải, thì tôi không thấy bất kỳ lý do nào để ném ngoại lệ khi vật liệu đó đã được tải.

Nếu xảy ra lỗi khi tải tài liệu, ví dụ, không thể mở kết nối cơ sở dữ liệu hoặc không có "gỗ" trong kho, thì việc ném một ngoại lệ để thông báo cho người gọi về vấn đề đó là chính xác.


-2

Tại sao không thay đổi phương thức để nó trả về 'true', đó là vấn đề được thêm vào và 'false' nếu không?

private bool LoadMaterial(string name)
{
   if (_Materials.ContainsKey(name))

    {

        return false; //already present
    }

    _Materials.Add(
        name,
        Resources.Load(string.Format("Materials/{0}", name)) as Material
    );

    return true;

}

15
Các hàm trả về giá trị lỗi chính xác là kiểu chống ngoại lệ được cho là lỗi thời.
Philipp

Luôn luôn là trường hợp này sao? Tôi nghĩ đó chỉ là trường hợp với semipredicate ( en.wikipedia.org/wiki/Semipredicate_probols ) Bởi vì trong mẫu mã OP, việc không thêm tài liệu vào hệ thống là không có vấn đề thực sự. Phương pháp nhằm mục đích đảm bảo rằng vật liệu có trong hệ thống khi bạn chạy nó và đó chính xác là những gì phương thức này làm. (ngay cả khi nó không thành công) Boolean trả về chỉ cho biết liệu phương thức đã cố gắng thêm vấn đề này hay chưa. ps: Tôi không xem xét rằng có thể có nhiều vật chất có cùng tên.
MrIveck

1
Tôi nghĩ rằng tôi đã tự mình tìm ra giải pháp: en.wikipedia.org/wiki/ Từ Điều này chỉ ra rằng câu trả lời của Ixrec là đúng nhất
MrIveck 23/1/2015

@Philipp Trong trường hợp bộ mã hóa / spec đã quyết định rằng không có lỗi khi bạn cố tải hai lần. Theo nghĩa đó, giá trị trả về không phải là giá trị lỗi mà là giá trị thông tin.
dùng949300
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.