if (popup1() === random)
соответственно здесь строго сравнивается undefined с числом, что всегда даст false.if (agreement === true)
зачем === true в условии, если agreement всегда типа boolean? ...form.formParams.errorList[formIndex]
// допустим у нас есть следующие переменные с типами:
let obj: Obj;
let value: T;
// мы их собираем в такой объект:
const newObj = { ...obj, k: value };
тип для newObj компилятор будет выводить из контекста и получит Obj & { k: T }
, ровно из того, что мы объединяем эти сущности.let objs: Obj[];
let value: T;
let key: string;
const newObj = { ...objs[1], [key]: value };
Тип на выходе будет ужеObj & { [key: string]: string }
, хотя objs на это раз у нас массив, компилятор видит, что мы берем индекс.Obj[]
у нас будет Obj[] | Obj[][]
?Obj | Obj[]
.(Obj | Obj[]) & { [key: string]: string }
, тут еще Важно понимать, что типы в TS - это чистая математика, и данный тип полностью равносилен такому:(Obj & { [key: string]: string }) | (Obj[] & { [key: string]: string })
{ [key: string]: string }
? Мы сможем свернуть тип, упростив уравнение на типах:(Obj & Obj) | (Obj[] & Obj)
(Obj) | (Obj[] & Obj)
(Obj & Obj[]) | (Obj & Obj)
(Obj & Obj[]) | (Obj)
Obj & Obj[]
И это именно тот тип, который получил у Вас компилятор temp = temp.into_iter().rev().collect();
(0..cols).for_each(|col| vec[row][col] = temp[col]);
temp
владеет некоторой памятью(0..cols).for_each
итерирует и вызывает переданную ему функцию cols раз|col| vec[row][col] = temp[col]
, а так как temp захвачен замыканием по значению (по сути он является частью замыкания), то в конце итерации цикла внутри for_each еще и само замыкание дропается.index out of bounds: the len is 2 but the index is 2Это не ошибка компиляции, а runtime panic, которая говорит о там, что Вы вышли за границу слайса
while (0..rows).map(|r| vec[r].first().unwrap()).all(|&x| x == 0) {
(0..rows).for_each(|r| {vec[r].remove(0);});
};
Насколько критичной проблемой для программиста является ручное управление памятью, которое называют недостатком языка Си?Неосвобожденная память (утечка памяти) - это самое безобидное, что может произойти.
Новый язык программирования Раст, как заявляют, лишен этого недостатка
но разве число ошибок в программе зависит именно от наличия или отсутствия ручного управления памятьюВ Rust ручное управление памятью, как и в C и в C++, просто есть культура, что если некая структура аллоцировала память, то она ее освободит. Всякие Vec, Box и т.д. делают это в Drop. В C++ многие повседневные типы так же освобождают в деструкторе память, которую они выделили. Однако в Rust есть разделение на safe и unsafe код и для прикладного программирования safe возможностей более чем достаточно. В C++ же весь код unsafe.
разве общее число ошибок не перераспределяется на другие недостатки программыНет, не перераспределяется. Хорошая система типов действительно может избавить от многих ошибок, что в целом сделает ПО более надежным. Но надо понимать, что от всех ошибок не избавит ни что. Банальная дискоммуникация с заказчиком порождает огромное число багов.
являются ли ошибки с памятью ошибками программиста, а не компилятора и языка программированияБезусловно это ошибки программиста. Программисты, как правило, - это люди, а людям свойственно ошибаться. И хорошо, когда есть средства статического анализа, которые помогают предотвращать ошибки до выхода ПО в продакшн.
export type ApiResponse<T> =
| { errors: Array<{ [key: string]: string }> }
| { data: Array<T> }
| { text: string };
abstract class Api<T> {
protected readonly baseUrl: string;
protected readonly endPoint: string;
protected get url(): string {
return new URL(this.endPoint, this.baseUrl).toString();
}
protected constructor(baseUrl = '/', endPoint: string) {
this.baseUrl = baseUrl;
this.endPoint = endPoint;
}
protected async http({
url = '',
method = 'GET',
data = undefined,
}: RequestData): Promise<ApiResponse<T>> {
try {
const response: Response = await fetch(
(new URL(url, this.url).toString()),
{ method, body: data }
);
return await response.json();
} catch (e) {
console.error(e.message);
return { text: e.message };
} finally {
// finnally
}
}
}
class ApiPost extends Api<Post> {
constructor(baseUrl: string, endPoint: string) {
super(baseUrl, endPoint);
}
async list(count?: number): Promise<false | Array<Post>> {
const response: ApiResponse = await this.http({
url: `${count ? `?_limit=${count}` : ''}`,
});
if (Array.isArray(response))
return response;
return false;
}
}
let chunks = '';
req.on('data', chunk => {
chunks += chunk;
});
const filePath = `../source/archive.zip`;
const reader = fs.createReadStream(filePath);
const options = {
hostname: url.hostname,
port: 443,
path: url.pathname,
method: 'PUT',
headers: {
'Content-Type': 'application/zip',
'Content-Length': fs.statSync(filePath).size
}
};
const req = https.request(options, res => {
res.on('error', err => console.log('ошибка:', err));
res.on('end', () => console.log('отправлено'));
});
reader.pipe(req);
router.put('/', (req, res, next) => {
const pathToFile = path.join(__dirname, '../public/uploads/archive.zip');
const writer = fs.createWriteStream(pathToFile);
req.pipe(writer).once('error', next).once('finish', () => {
res.send('файл сохранён');
});
});
if (localStorage.getItem('theme') !== null) {
localStorage.getItem('theme') // эта строка ничего не делает
}
(function () {
const blue = document.querySelector('#pink')
switch (localStorage.getItem('theme')) {
case 'blueTheme':
blue.classList.add('blueTheme')
}
blue.addEventListener('click', () => {
if (blue.classList.contains('blueTheme')) {
blue.classList.add('blueTheme')
localStorage.setItem('theme', 'blueTheme')
} else {
blue.classList.remove('blueTheme')
localStorage.removeItem('theme')
}
})
}())