Я действительно не понимаю разницы между #encode
и #force_encoding
в Ruby для класса String
. Я понимаю, что "kam".force_encoding("UTF-8")
заставит "kam"
быть в кодировке UTF-8, но как #encode(encoding)
отличается?
В чем разница между #encode и #force_encoding в ruby?
Ответ 1
Разница довольно большая. force_encoding
устанавливает заданное строковое кодирование, но не меняет сама строка, т.е. не изменяет ее представление в памяти:
'łał'.bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII').bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII') #=> "\xC5\x82a\xC5\x82"
Кодирование предполагает, что текущая кодировка верна и пытается изменить строку, чтобы она читала то же самое во второй кодировке:
'łał'.encode('UTF-16') #=> 'łał'
'łał'.encode('UTF-16').bytes #=> [254, 255, 1, 65, 0, 97, 1, 66]
Короче говоря, force_encoding
изменяет способ чтения строки из байтов, а encode
изменяет способ записи строки без изменения вывода (если возможно)
Ответ 2
Прочитайте это Изменение кодировки
Связанное кодирование строки может быть изменено двумя разными способами.
Во-первых, можно установить
Encoding
строки в новую кодировку без изменения внутреннего байтового представления строки, сString#force_encoding
. Вот как вы можете указать Ruby правильное кодирование строки.
Пример:
string = "R\xC3\xA9sum\xC3\xA9"
string.encoding #=> #<Encoding:ISO-8859-1>
string.force_encoding(Encoding::UTF_8) #=> "R\u00E9sum\u00E9"
Во-вторых, можно перекодировать строку, т.е. перевести ее внутреннее представление байта в другое кодирование. Его связанное кодирование также устанавливается на другое кодирование. См.
String#encode
для различных форм транскодирования и класс Encoding:: Converter для дополнительного контроля над процессом перекодирования.
Пример:
string = "R\u00E9sum\u00E9"
string.encoding #=> #<Encoding:UTF-8>
string = string.encode!(Encoding::ISO_8859_1)
#=> "R\xE9sum\xE9"
string.encoding
#=> #<Encoding::ISO-8859-1>