Неизменное Строковое недоразумение или ошибка в Документах?

То, что вы спрашиваете, не имеет смысла. Возможно, у вас есть файл .tar.gz или .tgz?

На домашней странице Gzip ( https://www.gzip.org/ ):

gzip - это утилита сжатия данных без потерь для одного файла / потока, в которой полученный сжатый файл обычно имеет суффикс .gz.

blockquote>

Gzip-файл - это просто сжатый поток байтов. С точки зрения файлов, распаковка файла .gz всегда приводит к одному файлу. Формат не предусматривает разбиения содержимого полученного файла на несколько файлов или присвоения им имен.

Существуют и другие форматы файлов, в которых хранятся несколько файлов. Tar обычно используется для тех же кругов, где используется Gzip. Файлы Tar обычно имеют расширение .tar. Но когда создается Tar, он часто сразу сжимается с помощью Gzip. Так что вы часто находите в дикой природе файлы с расширением .tar.gz. Это означает, что один или несколько файлов были собраны в один файл Tar, а затем этот файл был сжат с помощью Gzip. Этот сценарий настолько распространен, что одно расширение, .tgz, часто используется в качестве ярлыка для .tar.gz. Кроме того, Tar сам может выполнять сжатие Gzip, поэтому для создания файла .tgz из каталога файлов вы можете сделать следующее:

tar -czf archive.tgz somedirectoryname

Если вы на самом деле Если у вас есть файл .tar.gz или .tgz, то способ распаковать и развернуть этот файл в несколько файлов - сначала распаковать его с помощью Gzip, а затем извлечь отдельные файлы с помощью Tar. Tar может сам выполнять распаковку Gzip, поэтому все, что вам нужно сделать для распаковки файла .tgz:

tar -xzf archive.tgz

Это создаст все файлы и структуру каталогов, которые использовались создать файл .tgz.

Если у вас действительно есть только файл .gz, то я не уверен, что у вас есть, если вы ожидаете, что он естественно расширится в несколько файлов. Файл .gz просто не может самостоятельно сохранить понятие нескольких файлов. Я предполагаю, что у вас есть сжатые Gzip отдельные файлы журналов.

5
задан 9 October 2008 в 15:07
поделиться

12 ответов

Люди, кажется, не понимают вопроса. Никто не утверждает, что строковые объекты не неизменны. Предмет спора что он полужирный:

и переменная b продолжает содержать "h"

Я соглашаюсь с OP, что эта часть документа является неправильной на двух количествах:

(1) В очевидном интуитивном смысле, что, если Вы печатаете (b) (или независимо от того, что корректный оператор находится на этом языке) после его двух демонстрационных строк Вы доберетесь "привет" как результат.
(2) В строгом смысле, что переменная b не содержит "h", "привет", или любое строковое значение. Это содержит ссылку на строковый объект.

Содержание переменной b действительно изменяется в результате присвоения - это изменяется от точки для строкового представления объекта "h" к указателю для строкового представления объекта "привет".

То, когда, как они говорят, "содержат" то, что они действительно имеют в виду, является "точками к". И они неправы, после того, как присвоение b больше не указывает на "h".

Я думаю пример, который они действительно хотели дать, это:

string a = "h";
string b = a;
b += "ello";

Причем точка - то, что, я верю, неподвижная точка к "h"; т.е. присвоение на b не изменяет объект, на который это указывало, это создает новый объект и изменяет b для указания на него.

(Я на самом деле не пишу C#, но это - мое понимание.)

5
ответ дан 18 December 2019 в 06:04
поделиться

Вы сделали дополнение И присвоение за один шаг. Строки неизменны, но также и ссылочный тип.

string b = "h";
b = b + "ello";

Мы можем посмотреть на псевдопамять как это:

string b = "h";         // b    := 0x00001000 ["h"]
string tmp1 = "ello";   // tmp1 := 0x00002000 ["ello"]
string tmp2 = b + tmp1; // tmp2 := 0x00003000 ["hello"]
string b = tmp2;        // b    := 0x00003000 ["hello"]

Я не совсем уверен, где Вы получаете тот текст, потому что, поскольку я прочитал документацию для строкового класса, который я нахожу (не, что я думаю, что "h" на самом деле собран "мусор"):

Строки неизменны - содержание строкового объекта не может быть изменено после того, как объект создается, хотя синтаксис заставляет его появиться, как будто можно сделать это. Например, при написании этого кода компилятор на самом деле создает новый строковый объект содержать новую последовательность символов, и что новый объект присвоен b. Строка "h" затем имеет право на сборку "мусора".

Стрельба по тарелочкам @Jon поднимает это, "h" никогда не будет собираться "мусор" должный представить интернирование в виде строки, и я соглашаюсь с ним, но даже moreso Стандарт C# соглашается с ним, иначе следование §2.4.4.5 Строковые литералы не могло быть верным:

Каждый строковый литерал не обязательно приводит к новому строковому экземпляру. Когда два или больше строковых литерала, которые эквивалентны согласно строковому оператору равенства (§7.9.7), появляются в той же программе, эти строковые литералы относятся к тому же строковому экземпляру.

7
ответ дан 18 December 2019 в 06:04
поделиться

Да, документы являются неправильными. (Документы для многих строковых методов подразумевают переменчивость также. Они в основном плохо записаны.)

Heck, даже использование "компилятора" создание нового строкового объекта выключено. В основном это делает:

string b = "h";
b = string.Concat(b, "ello");

В той точке сделано задание компилятора - это - платформа, которая создает новый строковый объект.

4
ответ дан 18 December 2019 в 06:04
поделиться

Недоразумение здесь о ссылочных типах:
Строка является ссылочным типом, не типом значения. Это означает, Ваша переменная b не является объектом строки типа, это - ссылка на объект строки типа в памяти.
То, что говорит документ, то, что объект в памяти неизменен.
Однако, Ваша ссылка на объект может быть изменена для указания на некоторый другой (неизменный) объект в памяти.
Для Вас могло бы быть похоже, что содержание объекта изменилось, но в памяти это не имеет, и это - весь, о чем неизменная штука.

Сама строка неизменна. Что Вашим измененным примером не был строковый класс в памяти, но ссылка, Ваша переменная указывает.

См. этот немного измененный код:

string b = "h";
string m1 = b;
b += "ello";
// now b == "hello", m1 == "h"

В конце b укажет на "привет", в то время как m1 укажет на "h". Для Вас могло бы казаться, что "h" изменился на "привет", но это не имеет. b + = "ello" создал новый строковый класс, содержащий "привет", и присвоил его b, в то время как старый b все еще присутствует в Памяти и все еще содержит "b".

Если бы строка не была неизменна, то m1 содержал бы "привет" также вместо просто "b", потому что и b и m1 указали на ту же ссылку.

4
ответ дан 18 December 2019 в 06:04
поделиться

Документы являются неправильными. Переменная b теперь содержит "привет". Строка неизменна, но переменная может быть повторно присвоена.

4
ответ дан 18 December 2019 в 06:04
поделиться

Строка не может измениться, но строковой переменной можно присвоить другое значение. То, что Вы делаете, ближе к:

string b = "h";
string temp = b + "ello";
b = temp;

Для показа фактической неизменности строки это перестанет работать:

   string b="hello";
   if(b[0] == 'h')  // we can read via indexer
      b[0] = 'H';   // but this will fail.
2
ответ дан 18 December 2019 в 06:04
поделиться

представьте b в виде строки = "h"; b + = "ello";

b является просто ссылкой для возражения в "куче". На самом деле, после "+ =" операция, b больше не ссылается к оригиналу "h". Теперь, это, которому ссылка на новую строку возражает "привет", который является конкатенацией "h" и "ello". Строка "h" будет собрана GC.

0
ответ дан 18 December 2019 в 06:04
поделиться

Существует теперь три строки. Каждый - оригинал "h", каждый - "ello", и третье "привет". Ваша b переменная указывает на "привет" строка. Другие две строки не имеют никаких ссылок на них и могут быть выброшены сборщиком "мусора".

1
ответ дан 18 December 2019 в 06:04
поделиться

То, что происходит, - то, что Вы делаете новую переменную, которая содержит 'привет', и затем изменяющийся b для ссылки на это, память для 'старого' b все еще содержит 'h', но это больше не необходимо так, сборщик "мусора" очистит его. Поэтому настолько хорошо использовать stringbuilders при итерации, и липкие строки вместе - видят это для большего количества информации.

0
ответ дан 18 December 2019 в 06:04
поделиться

Я не знаю то, что делает C#, но я действительно читал об этом в Java, и реализация на основе Java будет больше похожа на это:

представьте b в виде строки = "h";

b = (новый StringBuilder (b)).Append ("ello").ToString ();

Дело в том, что "+" или "Добавляют", не существует для строки, потому что строка неизменна.

0
ответ дан 18 December 2019 в 06:04
поделиться

Проще говоря, строки не могут быть изменены на месте (если строка является массивом символов),

0
ответ дан 18 December 2019 в 06:04
поделиться

Попробуйте это:

string b = "h";
string c = b + "ello";    // b still == "h", c = "hello"
string d = string.concat(b, "ello"); // d == hello, b still "h"

Почему b все еще "h"? Поскольку "b" не является объектом, это - ссылка на объект. Нет ничего, что можно сделать к объекту, на который ссылается b для изменения его. Если строки, где изменяемый затем использование:

string b = "ello";
string f = b.Insert("h",0);

изменил бы b к "привет" (потому что h был вставлен в положении 0), но поскольку это - неизменный b, остается "ello".

Если Вы изменяете ссылку на другой объект что другая вещь.

b = "ello";
b = "Some other string";
// b not references "Some other string" , but the object "ello" remains unchanged.

Я надеюсь, что это помогает (и работы :S)

0
ответ дан 18 December 2019 в 06:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: