Kiểm tra xem một biến có phải là một chuỗi trong Ruby không


Câu trả lời:


205

Tôi nghĩ rằng bạn đang tìm kiếm instance_of?. is_a?kind_of?sẽ trả về true cho các thể hiện từ các lớp dẫn xuất.

class X < String
end

foo = X.new

foo.is_a? String         # true
foo.kind_of? String      # true
foo.instance_of? String  # false
foo.instance_of? X       # true

9
Nếu không biết mục đích của câu hỏi, tôi sẽ nói đối với hầu hết các tình huống lập trình trong thế giới thực, is_a?đây thực sự là thành ngữ thích hợp hơn để sử dụng (và thường thì một câu kiểm tra đánh máy như Andrew Grimm đề cập thậm chí còn tốt hơn). So sánh lớp nghiêm ngặt thường là mùi mã. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

Nhanh chóng sang một bên: nếu bạn sử dụng điều này trong logic có điều kiện, bạn cần sử dụng dấu ngoặc đơn; ví dụ: if foo.is_a? (string) && ...
dan

Như mong đợi, cách tiếp cận này sẽ hoạt động không chỉ với String, mà còn với IntegerFloat. Nó cũng hoạt động cho Decimal? (văn bản siêu việt thông dịch viên nổi bật cú pháp khác nhau cho Decimalmà làm cho tôi nghi ngờ)
stevec

29

Một cách tiếp cận gõ vịt hơn sẽ là

foo.respond_to?(:to_str)

to_str chỉ ra rằng lớp của một đối tượng có thể không phải là con thực sự của Chuỗi, nhưng bản thân đối tượng đó rất giống chuỗi (stringy?).


Mát mẻ. Trong trường hợp này tôi xảy ra cho biết rằng foomột trong hai sẽ được true, falsehoặc một chuỗi vani, nhưng nó tốt để tìm hiểu các giải pháp tổng quát hơn.
davidchambers 13/10/11

kết hợp điều này với một cuộc gọi to_s sau khi kiểm tra xem đối tượng có đáp ứng với nó hay không và bạn đã có cho mình một chuỗi!
seanmakesgames, 31-07-16

1
@seanmakesgames Ý của bạn là to_str, hay to_s? Hai cái hơi khác nhau.
Andrew Grimm,


23

Bạn có thể làm:

foo.instance_of?(String)

Và tổng quát hơn:

foo.kind_of?(String)

4
Điều gì làm cho kind_oftổng quát hơn? Họ dường như đồng nghĩa: is_a.
davidchambers 13/10/11

2
@Davidchambers bạn nói đúng, 'kind_of?' là một từ đồng nghĩa với 'is_a?'.
steenslag

@davidchambers: Bạn nói đúng, ý tôi là instance_of?thay vì is_a?.
Federico Builes

7
foo.instance_of? String

hoặc là

foo.kind_of? String 

nếu bạn, bạn chỉ quan tâm nếu nó được lấy từ Stringđâu đó trong chuỗi kế thừa của nó


4

Ngoài các câu trả lời khác, Class định nghĩa phương thức === để kiểm tra xem một đối tượng có phải là một thể hiện của lớp đó hay không.

  • o.class lớp của o.
  • o.instance_of? c xác định xem o.class == c
  • o.is_a? c Có phải o là một thể hiện của c hay bất kỳ lớp con nào của nó không?
  • o.kind_of? c từ đồng nghĩa với * is_a? *
  • c === o cho một lớp hoặc mô-đun, xác định xem * o.is_a? c * ( Chuỗi === "s" trả về true)

-1

Tôi nghĩ một cách tốt hơn là tạo một số phương thức vị từ. Điều này cũng sẽ lưu "Điểm kiểm soát duy nhất" của bạn.

class Object
 def is_string?
   false
 end
end

class String
 def is_string?
   true
 end
end

print "test".is_string? #=> true
print 1.is_string?      #=> false

Cách gõ càng vịt;)


2
có gì sai với "string".is_a?(String). Có vẻ như bạn đang phát minh lại bánh xe. Ngoài ra còn có class, instance_of,kind_of , vv ... Xấu ý tưởng để vá khỉ các Objectlớp, chưa kể đến đó là không cần thiết.
Mohamad

Tôi hoàn toàn đồng ý với bạn :) Nếu bạn chỉ tập trung vào các loại primitve và bạn biết rằng các yêu cầu dự án của bạn liên quan đến các loại nguyên thủy sẽ không bao giờ thay đổi (ok thì thường là vậy;)) thì bạn vẫn ổn. Nhưng trong trường hợp các yêu cầu thay đổi thì tốt hơn là có một "Điểm kiểm soát duy nhất". Ví dụ: trong môi trường dự án của bạn, bạn có rất nhiều lần kiểm tra trước (1000 trở lên). pre_check("test".is_string?) Bây giờ yêu cầu dự án của bạn sẽ thay đổi và mọi Chuỗi có ba ký tự trở lên không còn được định nghĩa là Chuỗi nữa (tôi biết nó không bình thường;)) Bây giờ bạn có thể thay đổi phương thức của riêng mình một cách dễ dàng.
schlegel11
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.