Странности if i in [set]...

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
leo_bs
новенький
Сообщения: 10
Зарегистрирован: 27.01.2010 02:06:48
Откуда: Йошкар-Ола, Респ. Марий Эл
Контактная информация:

Странности if i in [set]...

Сообщение leo_bs »

компилирую программу в Lazarus'е под ubuntu, при помощи fpc...
имеется следующий кусок кода:

Код: Выделить всё

    
procedure ...
var arr: array of integer;
begin
...
  if i in arr then...
...
end;
 

при компиляции выдаёт ошибку:
Ошибка: Ожидается тип множества
при этом если вместо arr подставить что-то вроде [.., .. , ..] или сослаться на внешний массив элементов - ошибки не возникает...
почему?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Тип выражения справа от in должен быть "множество" (set). Аргумент другого типа, в том числе массив, там не допускается.
При использовании записи [.., ..] компилятор может понять ее как множество, если элементы не повторяются и меньше 255.
Climber
постоялец
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Сообщение Climber »

Sergei I. Gorelkin имел ввиду это:

Код: Выделить всё

procedure ...
var arr: set of integer;
begin
...
  if i in arr then...
...
end;
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Это я в виду не имел. Тип integer в качестве базового типа множества невозможен, максимум byte (не больше 255).
Climber
постоялец
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Сообщение Climber »

Я, в свою очередь, хотел акцентировать внимание на том, что array надо заменить на set. Или это не обязательно??? :shock:
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Обязательно :)
leo_bs
новенький
Сообщения: 10
Зарегистрирован: 27.01.2010 02:06:48
Откуда: Йошкар-Ола, Респ. Марий Эл
Контактная информация:

Сообщение leo_bs »

Любопытно... не обращал раньше на это внимания ) теперь буду умным и просвещённым человеком! Всем спасибо. :)
Tsukasa-mixer
новенький
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Сообщение Tsukasa-mixer »

Подниму тему.

Код: Выделить всё

if (sr.Attr <> faDirectory) and SR.Name in ['*.gif','*.png','*.jpg'] then ...  

за подобное компилер по репе ошибкой дает =/ ....
а я уже привык множества в делфе использовать в условиях =( или мб както подругому а не писать по студенчески

Код: Выделить всё

if (sr.Attr <> faDirectory) and
    ((SR.Name = '*.gif')or(SR.Name = '*.png')or(SR.Name = '*.jpg')) then
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

"умный" синтаксис развращает.

делфи теперь есть связка "regexp + set" ?

Код: Выделить всё

function isImageExt(const FileName: String): Boolean; 
var
  s: String;
  i : integer;
const
  images : array [0..2] of string = ('.png', '.gif','.jpg');
begin
  s:=AnsiLowerCase(ExtractFileExt(FileName));
  for i:=0 to length(images)-1 do begin
    Result:=(s = images[i]);
    if Result then Exit;
  end;
  Result:=false;
end;
...
if (sr.Attr <> faDirectory) and isImageExt(Sr.Name) then...

Последний раз редактировалось скалогрыз 06.04.2010 13:19:22, всего редактировалось 1 раз.
Tsukasa-mixer
новенький
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Сообщение Tsukasa-mixer »

скалогрыз писал(а):"умный" синтаксис развращает.

делфи теперь есть связка "regexp + set" ?

Код: Выделить всё

function isImageExt(const FileName: String): Boolean; 
var
  s: String;
  i : integer;
const
  images : array [0..2] of string = ('*.png', '*.gif','*.jpg');
begin
  s:=AnsiLowerCase(ExtractFileExt(FileName));
  for i:=0 to length(images)-1 do begin
    Result:=(s = images[i]);
    if Result then Exit;
  end;
  Result:=false;
end;
...
if (sr.Attr <> faDirectory) and isImageExt(Sr.Name) then...




Подобный вариант я также знаю - просто привел - пример =)
и да в делфе от Embarcadero можно в условиях вфождения во множества проверять не только цифренное, но и какое угодно.
(пару последних лет писал в Делфе 2009 - по студ. программе получил лицензию дак и писал. но увы всегда питал слабость к кросплатформенному программированию и жить дальше на делфе полностью уже не могу, да и модуле под делфю все платные =( а тут что называется с чистого листа, можно попробывать.)
и вышеописанный вариант в другой программе я решал вот так в делфе - с тарой проге одной =)

Код: Выделить всё

TMediaType = (mNull, mp3, ogg, flac, wav, wma, aac, ape, cda, bml);

function TDM.mediaType(Send: string): TMediaType;
begin
  Send := ExtractFileExt(send);
  Send := AnsiLowerCase(Send);
  if Send = '.mp3'  then begin result:=mp3;   exit; end;
  if Send = '.ogg'  then begin result:=ogg;   exit; end;
  if Send = '.flac' then begin result:=flac;  exit; end;
  if Send = '.wav'  then begin result:=wav;   exit; end;
  if Send = '.wma'  then begin result:=wma;   exit; end;
  if Send = '.aac'  then begin result:=aac;   exit; end;
  if Send = '.ape'  then begin result:=ape;   exit; end;
  if Send = '.cda'  then begin result:=cda;   exit; end;

  if Send = '.bml'  then begin result:=bml;   exit; end;
  result:=mNull;
end;

Ибо кейс в делфе иногда странно ведет себя с string значениями тоже по простому пришлось.
тут видимо подобным образом придется.

И еще вопрос - в вышеописанном коде вы проверял Result, он тут не вылетает по достижении Result'а из процедуры ?

Ну а в общем подход ваш использую - спасибо.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Tsukasa-mixer писал(а):и да в делфе от Embarcadero можно в условиях вфождения во множества проверять не только цифренное, но и какое угодно.

как я понял синтаксис

Код: Выделить всё

filename in ['*.jpg', '*.gif']

не просто проверяет соответсвие строк (filename='*.jpg' or filename=*.gif), а разбирает маску, и смотрит соответствие имени файла маске.
Т.е. скрытого кода за таким сравнением наворочена уйма. и об его эффективности (и правильности) можно судить, только смотря в ассемблерный код.

Настойчиво рекомендую всем использовать синтаксис Delphi 7. Проблем с портированием кода на FPC не возникнет.

Tsukasa-mixer писал(а):И еще вопрос - в вышеописанном коде вы проверял Result, он тут не вылетает по достижении Result'а из процедуры ?

не должен.
внёс поправочку. в расширениях символ * не нужен.
Tsukasa-mixer
новенький
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Сообщение Tsukasa-mixer »

внёс поправочку. в расширениях символ * не нужен.

Да я знаю.
не просто проверяет соответсвие строк (filename='*.jpg' or filename=*.gif), а разбирает маску, и смотрит соответствие имени файла маске.

Смотри пример реализации выше, там так реализовано т.к. потом в кейсе смотреть удобнее по форматам.
Т.е. скрытого кода за таким сравнением наворочена уйма. и об его эффективности (и правильности) можно судить, только смотря в ассемблерный код.

От чего и хочу линять с делфи, т.к. модули растут и растут и порой делая тривиальные вещи получаеш не тривиальные размерчики файлов =/ ...
так работая с одним модулем мультимедийный проекте добавление его в uses приводило прыжок размера Exe файла на 10мб =/, а при последующих расширениях возможностей размеры просто ужасали =( ...
вчера скачал лазарь и в принципе пока устраивает - особенно то что никто не норовит всю систему засунуть в один *.dcu файл =)
да и размеры exe файлов уже ближе к истине начинают быть похожи =)
еще бы найти реализацию KOL (зеркальных классов)

А и еще вернусь к filename in ['*.jpg', '*.gif']
я в принципе не говорил что он все проверит меня просто смутило что лазарь отказывается проверять вхождение во множество строковых значений, большего и не нужно. а изменить в принципе можно было вот так.

Код: Выделить всё

if (LowerCase(ExtractFileExt(SR.Name)) in ['.gif','.png','.jpg'] ) then ...

просто досадно что подобная проверка не прокатывает и нужно ухищряться.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

а почему бы не воспользоваться стандартной функцией?

Код: Выделить всё

uses strutils;
const
  exts:  array[0..2] of String = ('.gif','.png','.jpg');
begin
  if AnsiIndexStr(ExtractFileExt(SR.Name),exts)<>-1 then ...
Tsukasa-mixer
новенький
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Сообщение Tsukasa-mixer »

Mr.Smart писал(а):а почему бы не воспользоваться стандартной функцией?

Код: Выделить всё

uses strutils;
const
  exts:  array[0..2] of String = ('.gif','.png','.jpg');
begin
  if AnsiIndexStr(ExtractFileExt(SR.Name),exts)<>-1 then ...

Код: Выделить всё

AnsiIndexStr()

Не знаком ес чесно с данной функцией. - опробую , спс.!

Работает =) такой вариант уже ближе к истине.но с множествами придется осторожней обращаться )
Ответить