Это означает, что аргумент типа для перечисления должен произойти из перечисления, которое самого имеет тот же аргумент типа. Как это может произойти? Путем создания аргумента типа самим новым типом. Таким образом, если бы у меня есть перечисление под названием StatusCode, это было бы эквивалентно:
public class StatusCode extends Enum<StatusCode>
Теперь, если Вы проверяете ограничения, мы имеем Enum<StatusCode>
- так E=StatusCode
. Давайте проверим: E
расширяется Enum<StatusCode>
? Да! Мы хорошо.
можно спрашивать себя, какова точка этого:) Ну, это означает, что API для Перечисления может относиться к себе - например, способность сказать это Enum<E>
реализации Comparable<E>
. Базовый класс в состоянии сделать сравнения (в случае перечислений), но он может удостовериться, что только сравнивает правильный вид перечислений друг с другом. (РЕДАКТИРОВАНИЕ: Ну, почти - посмотрите редактирование в нижней части.)
я использовал что-то подобное в своем порте C# ProtocolBuffers. Существуют (неизменные) "сообщения" и "разработчики" (изменяемы, используются для создания сообщения) - и они стали парами типов. Включенные интерфейсы:
public interface IBuilder<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
Это означает, что из сообщения можно получить соответствующего разработчика (например, сделать копию сообщения и измениться на некоторые биты), и от разработчика можно получить соответствующее сообщение, когда Вы закончили создавать его. Это - хорошее задание, о котором пользователи API не должны на самом деле заботиться об этом, хотя - это страшно сложно и взяло несколько повторений для получения туда, где это.
РЕДАКТИРОВАНИЕ: Обратите внимание, что это не мешает Вам создать нечетные типы, которые используют аргумент типа, который сам является хорошо, но который не является тем же типом. Цель состоит в том, чтобы принести пользу в право случай, а не защитить Вас от неправильный случай.
Поэтому, если Enum
не были обработаны "особенно" в Java так или иначе, Вы могли (как отмечено в комментариях), создают следующие типы:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second
реализовал бы Comparable<First>
, а не Comparable<Second>
..., но First
самостоятельно будет прекрасен.
Есть действительно хорошая библиотека Perl для чтения xls: Spreadsheet :: ParseExcel .
Может быть xlrd выполнит работу (на Python)
edit: Мне действительно стоит научиться читать вопросы. Но написание csv не должно быть большой проблемой, так что, возможно, вы действительно сможете его использовать.
Вы можете использовать pyexcelerator в python.
Этот код (включен в папку examples
pyexcelerator как xls2csv.py
) извлекает все листы из электронных таблиц и выводит их в stdout
как CSV.
Вы можете легко изменить код, чтобы делать то, что вы хотите.
Самое замечательное в pyexcelerator - это то, что вы также можно использовать его для записи / создания файлов Excel xls без установки Excel.
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: xls2csv.py,v 1.1 2005/05/19 09:27:42 rvk Exp $"""
from pyExcelerator import *
import sys
me, args = sys.argv[0], sys.argv[1:]
if args:
for arg in args:
print >>sys.stderr, 'extracting data from', arg
for sheet_name, values in parse_xls(arg, 'cp1251'): # parse_xls(arg) -- default encoding
matrix = [[]]
print 'Sheet = "%s"' % sheet_name.encode('cp866', 'backslashreplace')
print '----------------'
for row_idx, col_idx in sorted(values.keys()):
v = values[(row_idx, col_idx)]
if isinstance(v, unicode):
v = v.encode('cp866', 'backslashreplace')
else:
v = str(v)
last_row, last_col = len(matrix), len(matrix[-1])
while last_row < row_idx:
matrix.extend([[]])
last_row = len(matrix)
while last_col < col_idx:
matrix[-1].extend([''])
last_col = len(matrix[-1])
matrix[-1].extend([v])
for row in matrix:
csv_row = ','.join(row)
print csv_row
else:
print 'usage: %s (inputfile)+' % me
Возможно, я уже нашел приемлемый ответ:
Но интересно услышать, какие еще варианты есть, или об инструментах на других языках.
Параметры существуют для всех трех языков. Вопрос в том, какой из них вам наиболее знаком. Это тот язык, который вы обязательно должны использовать. И если вы не знакомы ни с одним из этих языков, это приложение на самом деле не лучший пример выбора между языками.
Мнение PS: если вы не знаете ни одного из языков, просто изучите Python и используйте xlrd
.
Для python есть несколько вариантов, см. здесь , здесь и здесь . Обратите внимание, что последний вариант работает только в Windows с установленным Excel.
В Ruby вот код, который я использую: (требуется отличный гем parseexcel) require 'parseexcel'
def excelGetSheet(worksheet)
sheet=Array.new
worksheet.each { |row|
if row != nil # empty row?
cells=Array.new
j=0
row.each { |cell|
cells << cell.to_s('latin1') unless cell == nil
j=j+1
}
sheet << cells
end
}
return sheet
end
workbook = Spreadsheet::ParseExcel.parse("MyExcelFile.xls")
sheet1 = excelGetSheet(workbook.worksheet(0))
puts sheet1.inspect
для Ruby, Электронная таблица Gem отлично подходит для чтения записи Modify, ... Excels файлы