Przyjrzyjmy się różnicom między używaniem metody instancji String#to_i a metodą modułową Kernel::Integer. Najpierw jednak niech osadzić później w innej metodzie int1
:
def int1(str)
Integer(str) rescue nil
end
ten sposób, jeśli str
nie może być interpretowane jako liczba całkowita, Integer
podniesie wyjątek ArgumentError
, powodując Rescue in-line, aby powrócić nil
. Jeśli Integer
nie podniesie wykonania, to zwróci całkowity odpowiednik łańcucha.
Aby zaokrąglić porównania, dodajmy również wyrażenie regularne, które potwierdza, że zawartość ciągu reprezentuje liczbę całkowitą, przed użyciem to_i
do konwersji.
R =/
(?<=\A|\s) # match beginning of string or whitespace character (positive lookbehind)
-? # optionally match a minus sign
\d+ # match one or more digits
(?=\s|\z) # match whitespace character or end of string (positive lookahead)
/x # free spacing regex definition mode
def int2(str)
str =~ R ? str.to_i : nil
end
jak w int1
jeśli str
nie mogą być rozumiane jako liczba całkowita, int2
powróci nil
; else, int
zwraca całkowity odpowiednik ciągu.
Spróbujmy porównań.
str = '3'
str.to_i #=> 3
int1(str) #=> 3
int2(str) #=> 3
str = '-3'
str.to_i #=> -3
int1(str) #=> -3
int2(str) #=> -3
str = '3.0'
str.to_i #=> 3
int1(str) #=> nil
int2(str) #=> nil
str = '3.2'
str.to_i #=> 3
int1(str) #=> nil
int2(str) #=> nil
1e3 #=> 1000.0
str = '1e3'
str.to_i #=> 1
int1(str) #=> nil
int2(str) #=> nil
str = '-1e3'
str.to_i #=> -1
int1(str) #=> nil
int2(str) #=> nil
str = '- 1e3'
str.to_i #=> 0
int1(str) #=> nil
int2(str) #=> nil
str = '3a'
str.to_i #=> 3
int1(str) #=> nil
int2(str) #=> nil
str = '1-3a'
str.to_i #=> 1
int1(str) #=> nil
int2(str) #=> nil
str = 'b3'
str.to_i #=> 0
int1(str) #=> nil
int2(str) #=> nil
String#to_i odczytuje cyfry (ewentualnie poprzedzone znakiem minus) aż czyta spacją lub osiągnie koniec łańcucha. Następnie konwertuje tylko te cyfry i możliwy znak minus na Fixnum
, który zwraca. to_i
z pewnością ma swoje zastosowania, ale te przykłady pokazują, że powinieneś użyć int1
lub int2
, jeśli chcesz zwrócić nil
, jeśli ciąg nie zawiera reprezentacji liczby całkowitej.
Niesamowita odpowiedź. Dzięki. – Nobita
Zauważ, że możesz określić podstawę dla obu, ['Kernel # Integer'] (http://ruby-doc.org/core-2.3.1/Kernel.html#method-i-Integer) i [String # to_i'] (http://ruby-doc.org/core-2.3.1/String.html#method-i-to_i). – Stefan
Innym ważnym przykładem jest '' 'nil.to_i # => 0''' podczas gdy' '' Integer (zero) # => rzuca TypeError: nie można przekonwertować zero na liczbę całkowitą '' ' – Levsero